/* --shadow-card, --shadow-card-hover and --radius-lg now live in
   tokens.css (the shared design-token layer) — this file is card-specific
   rules only, not a second source of truth for those values. */

/* The artboard's About grid is `gap:64px`; the columns' blockGap emits
   nothing (theme.json enables none), so core's `:where()` 2em applied. */
.wp-block-columns.nr-about-columns {
	column-gap: 64px;
}

/*
 * The About portrait's burnt-orange offset block (patterns/about.php,
 * `.nr-about-photo` column) — the artboard draws it as a plain absolutely
 * positioned sibling `<div>` behind the photo (top:22px, left:22px, same
 * size, `--radius-lg`), which a block-editor `core/image` can't emit
 * itself. A `::before` pseudo-element on the column reproduces the same
 * visual without inventing a second, non-block-editable image slot.
 *
 * `core/columns` stretches every column to the row's tallest by default
 * (`align-items: normal`, which resolves to `stretch` for a flex item) —
 * unlike the artboard's own `align-items: center` grid. Against the text
 * column's four paragraphs that stretched this one far past the photo's
 * own 520px, and since the offset block's `height: 100%` below follows
 * that stretched box, not the photo, the orange block ended up
 * substantially taller than the photo it sits behind. `align-self: center`
 * makes the column (and therefore the offset block) size to its own
 * content instead, matching the artboard's vertical-centring intent.
 */
.nr-about-photo {
	position: relative;
	align-self: center;
}

.nr-about-photo::before {
	content: "";
	position: absolute;
	top: 22px;
	left: 22px;
	width: 100%;
	height: 100%;
	background: var(--wp--preset--color--burnt-orange);
	border-radius: var(--radius-lg);
	z-index: 0;
}

.nr-about-photo .wp-block-image {
	position: relative;
	z-index: 1;
	margin: 0;
}

.nr-about-photo img {
	display: block;
	width: 100%;
	height: 520px;
	object-fit: cover;
	border-radius: var(--radius-lg);
}

/*
 * Work row (patterns/work-row.php): the artboard scrolls its cards in one
 * horizontal row (`display:flex;overflow-x:auto`, no wrap) rather than
 * wrapping them onto multiple lines.
 */
.nr-work-row {
	flex-wrap: nowrap;
	overflow-x: auto;
	padding-left: var(--section-pad-x);
	padding-right: var(--section-pad-x);
}

.nr-work-row .nr-work-card {
	flex: 0 0 280px;
	width: 280px;
}

/*
 * Round 3, Finding 4: the two SectionHeading eyebrows (What I bring,
 * Let's connect) render as plain paragraphs, not the vendored
 * `SectionHeading.jsx` component — but its exact spec (`_ds_bundle.js`)
 * still applies: `opacity:.65` (never set here before) and a 14px gap to
 * the heading that follows (previously whatever the theme's default
 * block-to-block spacing happened to be, not this value). The eyebrow's
 * own margin-bottom is the single source of that gap — the heading itself
 * needs no margin-top, so there is nothing to collide with the round-2
 * `.nr-section > *:first-child` margin fix.
 */
.nr-eyebrow {

	/* The design's .65 measured 4.27:1 on lime (below AA's 4.5:1 for this
	   13px text); .75 is 5.68:1 there and 7.27:1 on off-white. */
	opacity: 0.75;
	margin-bottom: 14px;
}

/*
 * The eyebrow's own margin-bottom above is meant to be the *only* gap to
 * the heading that follows — but the heading also gets core's default
 * constrained-layout margin-top (round 2's `.nr-section > *:first-child`
 * fix only ever zeroed the *first* child of a section; an eyebrow's
 * heading is always the second), and adjacent margins collapse to
 * whichever is larger, not the eyebrow's smaller 14px. Confirmed live:
 * the gap was 47.8px (the heading's own margin-top) before this rule.
 */
.nr-eyebrow + * {
	margin-block-start: 0;
}

/*
 * Round 3, Finding 10: the footer's own site-logo, added alongside the
 * existing text wordmark — `parts/footer.html` gives it this class.
 * `.wp-block-site-logo img` (sections.css) already constrains the header's
 * copy of this SVG to 48px; a footer mark reads better smaller.
 */
.nr-footer-logo img {
	width: 32px;
}

/*
 * Round 4, Finding 5: "Copyright © 2026 — Nathaly Rojas" is three flex
 * siblings (the year has to stay a real, editable `nr/year` block, not
 * static text), and the group's own `blockGap` was adding a gap on
 * *both* sides of the year on top of nothing — neither adjacent
 * paragraph's text carries a space of its own, so the gap alone was the
 * only separator, and at 6.5px (this row's `font-size:small` context) it
 * read as roughly double a normal inter-word space rather than one.
 * `.nr-copyright`'s own blockGap is zeroed (parts/footer.html); this
 * gives `.nr-year` a single, explicit inline margin instead, sized to
 * read as one normal space on each side.
 */
/*
 * The group's `blockGap: 0` in parts/footer.html never reaches the rendered
 * markup — WordPress emits no inline gap for it, so core's flex-layout
 * default of 0.5em applies and stacks on top of the year's own margin,
 * which is what produced the visible double space either side of it.
 * Zero the container's gap explicitly and let the margin below be the only
 * separator.
 */
.nr-copyright {
	gap: 0;
}

.nr-copyright .nr-year {
	margin-inline: 0.32em;
}

/*
 * What I bring (patterns/what-i-bring.php) is a two-column grid on the
 * artboard (`grid-template-columns: repeat(2,1fr)`), authored as a
 * wrapping flex group (core/group has no CSS-grid layout type), so the
 * column count comes from each card's own flex-basis instead.
 */
.nr-skill-card {
	flex: 1 1 calc(50% - 12px);
	min-width: 280px;
}

/*
 * The artboard's `gap:24px` between the four cards. theme.json enables no
 * blockGap, so the group's own gap control emits nothing and core's
 * zero-specificity `:where(.is-layout-flex){gap:0.5em}` (8px) applied —
 * which also let each card grow 8px past its `calc(50% - 12px)` basis.
 */
.wp-block-group.nr-skill-grid {
	gap: 24px;
}

/*
 * This is what I do (patterns/proof-points.php) — round 3, Finding 5: the
 * artboard is an actual `grid-template-columns: repeat(3,1fr)` with equal
 * card heights coming from the grid's own default `align-items: stretch`,
 * not a wrapping flex group. `core/group` has no CSS-grid layout type to
 * pick in the editor, so `.nr-proof-grid` (patterns/proof-points.php's own
 * group `className`) opts this one group out of core's `is-layout-flex`
 * display and into a real grid — the flex-basis approach the two-column
 * section above still uses can't guarantee equal row heights the way a
 * grid does natively.
 */
.wp-block-group.nr-proof-grid {
	display: grid;
	grid-template-columns: repeat(3, 1fr);
	gap: 24px;
	/* Core's own `.is-layout-flex` rule (still matching — WP always adds
	   its own layout classes alongside this one) sets `align-items:
	   center`, left over from the flex display it also sets. Grid honours
	   the same property name for its own, different purpose — "don't
	   stretch items across the row" — which is exactly why equal height
	   never happened here just from switching `display` to `grid` alone. */
	align-items: stretch;
}

/*
 * Responsive rules. The design declares ZERO breakpoints (docs/design-
 * digest.md § Breakpoints) — every value below is inferred, not vendored,
 * and is recorded as such in that same section. Chosen at the width the
 * digest's own table already names for each fixed grid, so this only
 * implements a decision already written down, not a new one.
 */
@media (max-width: 900px) {

	/* Only the photo takes the 4/5 ratio. The offset block keeps
	   `height:100%` of the column, i.e. of the photo — given its own ratio
	   it stood 4/5 of the column's width tall even with no photo in the
	   column, and overflowed into the wave below. */
	.nr-about-photo img {
		height: auto;
		aspect-ratio: 4 / 5;
	}

	.wp-block-group.nr-proof-grid {
		grid-template-columns: 1fr;
	}
}

@media (max-width: 720px) {

	.nr-skill-card {
		flex-basis: 100%;
	}
}

/*
 * The Elsewhere masonry (docs/design-digest.md § Breakpoints: "~800px").
 * Only possible now that render.php sets a custom property instead of a
 * literal column-count — see the comment above .nr-gallery.
 */
@media (max-width: 800px) {

	.nr-gallery {
		--nr-gallery-columns: 2;
	}
}

@media (max-width: 560px) {

	.nr-gallery {
		--nr-gallery-columns: 1;
	}
}

/*
 * nr/photo-gallery's masonry is plain CSS multi-column
 * (`column-count`/`column-gap`, set inline by render.php) — never true
 * masonry, which balances *content height*, not figure boundaries. Left
 * unconstrained, a tall photo can be split mid-figure across two columns:
 * the browser renders part of its image in each column, and the resulting
 * element spans both, so a click meant for its trigger button can land on
 * whatever sits in the *other* column at that point instead. Task 14's
 * seeder is what first populated this grid with enough photos, of varied
 * enough heights, to make that reachable — see its report for the e2e
 * evidence. `break-inside: avoid` keeps every figure whole in one column.
 *
 * The bigger half of that same bug: `render.php` never wraps its `<img>`
 * in `.wp-block-image`, so it never inherits core's block-library rule
 * that scales an image down to its container. Without a rule here, the
 * browser renders the image at its own registered-size width (e.g. 768px)
 * regardless of the ~360px column it sits in, so the `<button>` around it
 * (shrink-wrapped, `inline-block`) grows to match and spills into the next
 * column — which is what a neighbouring photo was actually intercepting
 * clicks for. `width: 100%` on both the trigger and the image is what
 * makes each figure genuinely one column wide.
 *
 * The column count itself used to be a literal `column-count:N` written
 * inline by render.php — correct for the initial render, but no external
 * stylesheet rule can ever override a property an inline `style`
 * attribute already sets on that same element, a media query included,
 * short of `!important`. render.php now sets `--nr-gallery-columns-base`
 * instead (still inline, still per-instance, still driven by the
 * block's own `columns` attribute) — a *different* custom property from
 * the one `column-count` actually reads below. A breakpoint can freely
 * declare `--nr-gallery-columns` on `.nr-gallery` (an ordinary external
 * rule, nothing inline to lose to) and win the `var()` fallback chain;
 * with no breakpoint active, neither declares it, and the chain falls
 * through to the inline per-instance default.
 */
.nr-gallery {
	column-count: var(--nr-gallery-columns, var(--nr-gallery-columns-base, 3));
}

/* The row gap. render.php sets --nr-gallery-gap from the block's `gap`
   attribute (the same value as its inline column-gap), so an item's own
   markup never carries it and a fetched item matches a rendered one. */
.nr-gallery__item {
	position: relative; /* Containing block for .nr-gallery__edit. */
	margin: 0 0 var(--nr-gallery-gap, 20px);
	break-inside: avoid;
	-webkit-column-break-inside: avoid;
	page-break-inside: avoid;
}

/*
 * With JavaScript, view.js swaps the multi-column flow above for N real
 * column containers and appends each photo to whichever is shortest, so a
 * new batch never reflows the photos already on screen (CSS columns
 * rebalance everything on every append). N still comes from the
 * --nr-gallery-columns custom properties above — the breakpoints stay in
 * this file only. The inline column-gap applies to the flex row as-is.
 * The editor canvas never runs view.js and keeps the no-JS layout.
 */
.nr-gallery.nr-gallery--js {
	display: flex;
	align-items: flex-start;
	column-count: auto;
}

/* A flex column (not a block) so the last item's margin stays inside the
   column's measured height instead of collapsing through it. */
.nr-gallery__col {
	display: flex;
	flex: 1 1 0;
	flex-direction: column;
	min-width: 0;
}

.nr-gallery__more {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 12px;
	margin-top: 24px;
}

/* The on-dark outline button (cards.css, is-style-on-dark), on the ink
   Elsewhere section. Qualified by the wrapper to out-rank
   a.wp-element-button and core's :where(.wp-element-button). */
.nr-gallery__more .nr-gallery__more-button {
	display: inline-block;
	padding: 14px 28px;
	border: 2px solid var(--wp--preset--color--off-white);
	background-color: transparent;
	box-shadow: none;
	color: var(--wp--preset--color--off-white);
	text-decoration: none;
}

.nr-gallery__more .nr-gallery__more-button:hover,
.nr-gallery__more .nr-gallery__more-button:focus-visible {
	background-color: var(--wp--preset--color--off-white);
	color: var(--wp--preset--color--ink);
}

.nr-gallery__more .nr-gallery__more-button[aria-disabled="true"] {
	opacity: 0.6;
	cursor: progress;
}

.nr-gallery__more .nr-gallery__more-button[hidden] {
	display: none;
}

/* Editor-only (edit.js RandomOrderNote): the front end never renders it. */
.nr-gallery-note {
	margin: 0 0 16px;
	font-size: 13px;
	color: rgba(245, 245, 240, 0.85);
}

/* Visually hidden (still announced) unless it is reporting an error. */
.nr-gallery__status:not(.is-error) {
	position: absolute;
	width: 1px;
	height: 1px;
	margin: -1px;
	padding: 0;
	overflow: hidden;
	clip: rect(0, 0, 0, 0);
	white-space: nowrap;
	border: 0;
}

.nr-gallery__status.is-error {
	margin: 0;
	font-size: 14px;
	color: rgba(245, 245, 240, 0.8);
	text-align: center;
}

.nr-gallery__trigger {
	display: block;
	width: 100%;
	padding: 0;
	border: 0;
	background: none;
	cursor: pointer;
}

.nr-gallery__img {
	display: block;
	width: 100%;
	height: auto;
}

/* Fade in on load (gallery.js fadeIn()). JS-only, so without it every photo
   is simply visible; motion.css shortens it under reduced motion. The box
   keeps its aspect-ratio while transparent, so nothing shifts. */
.nr-gallery--js .nr-gallery__img {
	opacity: 0;
	transition: opacity 400ms var(--nr-ease);
}

.nr-gallery--js .nr-gallery__img.is-loaded {
	opacity: 1;
}

/*
 * PhotoRenderer::render_edit_link(): signed-in editors only. Pinned to the
 * photo's top-left corner; the figure is its containing block. Hidden in
 * the editor canvas, where the block is already being edited.
 */
.nr-gallery__edit {
	position: absolute;
	top: 8px;
	left: 8px;
	z-index: 1;
	padding: 4px 10px;
	border-radius: 999px;
	background-color: var(--wp--preset--color--off-white);
	color: var(--wp--preset--color--ink);
	font-size: 12px;
	font-weight: 600;
	line-height: 1.4;
	text-decoration: none;
}

.nr-gallery__edit:hover,
.nr-gallery__edit:focus-visible {
	background-color: var(--wp--preset--color--ink);
	color: var(--wp--preset--color--off-white);
	outline: 2px solid var(--wp--preset--color--off-white);
	outline-offset: 2px;
}

.editor-styles-wrapper .nr-gallery__edit {
	display: none;
}

/*
 * Round 3, Finding 11: captions were already in the DOM (render.php has
 * always emitted them; the seeder has always set a real caption on the
 * attachment `wp_get_attachment_caption()` reads) — confirmed live before
 * touching anything: figcaption present, correct text, `color: rgb(26,26,
 * 26)` (the root ink text default) on Elsewhere's ink background. The
 * fault was entirely a missing rule here, never the data or the render.
 */
.nr-gallery__caption {
	margin-top: 8px;
	font-size: 13px;
	color: rgba(245, 245, 240, .55);
}

/*
 * `nr/work-card`'s outer element is a native `<button>` (video cards) or
 * `<a>` (the Kiveo link card; a `<div>` until it has a URL) — render.php
 * never gives either a class the rest of this file resets, so both kept
 * every UA default: a `<button>`'s own grey background, 1px/6px padding and
 * border, and black text. Against the teal section that reads as a solid
 * near-white rounded card wrapping the frame and title, instead of the
 * artboard's translucent frame with the title sitting directly on the teal
 * below it (_design-source/Nathaly Rojas.dc.html: the work-card
 * `<a>`/wrapper is itself `display:flex;flex-direction:column;gap:14px`,
 * unstyled otherwise — the frame and title are its only two children).
 */
.nr-work-card {
	display: flex;
	flex-direction: column;
	gap: 14px;
	width: 100%;
	margin: 0;
	padding: 0;
	border: 0;
	background: none;
	color: inherit;
	text-align: left;
	text-decoration: none;
	cursor: pointer;
	font: inherit;
}

.nr-work-card__title {
	display: block;
	line-height: normal;
	font-family: var(--wp--preset--font-family--body);
	font-size: var(--wp--preset--font-size--card-title);
	font-weight: 500;
	color: var(--wp--preset--color--off-white);
}

/* The brief's card hover — "lift 4px, deeper shadow" — never made it into the
   vendored design code. Authored here, disabled under reduced motion in
   motion.css. */
.nr-card,
.nr-work-card__frame {
	transition: transform var(--nr-duration) var(--nr-ease), box-shadow var(--nr-duration) var(--nr-ease);
}

.nr-card:hover,
.nr-work-card:hover .nr-work-card__frame {
	transform: translateY(-4px);
	box-shadow: var(--shadow-card-hover);
}

/* A link card with no URL yet renders as a plain `<div>` (render.php) —
   nothing to click, so no pointer and no hover lift promising otherwise. */
.nr-work-card.nr-work-card--static {
	cursor: default;
}

.nr-work-card.nr-work-card--static:hover .nr-work-card__frame {
	transform: none;
	box-shadow: none;
}

/* Never a bare .wp-element-button: it ties with core's
   :root :where(.wp-element-button) and the tie breaks on load order, which
   differs between the canvas and the front end.
   Button.jsx's base style: a 2px transparent border on every variant (so a
   filled button is exactly as tall as an outlined one) and no line-height
   of its own — `normal`, not the root 1.65 that made the lg size 69px tall
   against the artboard's 66.
   `div.wp-block-button__link` is the canvas's button: core/button's edit
   renders its RichText as a div, so the `a` selector alone left every
   canvas button 69-73px tall. Same specificity; the front end never
   emits a div link, so this rule is inert there. */
a.wp-element-button,
button.wp-element-button,
div.wp-block-button__link {
	border-radius: 999px;
	border: 2px solid transparent;
	line-height: normal;
}

.is-style-nr-handwritten {
	font-family: var(--wp--preset--font-family--hand);
	color: var(--wp--preset--color--lime);
}

/* The artboard's tag row is `gap:12px`; the group's blockGap emits nothing
   (theme.json enables none), so core's `:where()` 0.5em applied instead. */
.wp-block-group.nr-role-tags {
	gap: 12px;
}

/* Tag.jsx, tone `on-dark` (the only tone the artboard uses): a
   `--border-on-dark` outline, not solid off-white, and line-height `normal`. */
.is-style-nr-tag {
	display: inline-flex;
	align-items: center;
	padding: 6px 14px;
	border-radius: 999px;
	border: 1.5px solid var(--border-on-dark);
	line-height: normal;
	font-size: var(--wp--preset--font-size--small);
	font-weight: 500;
	letter-spacing: 0.04em;
	text-transform: uppercase;
	margin: 0;
}

/*
 * The "Muted" paragraph style: secondary text in its surface's muted
 * colour (tokens.css sets `--nr-text-muted` per palette background, each
 * measured at 4.5:1 or better). A colour picked in the editor still wins.
 */
.is-style-nr-muted:not(.has-text-color) {
	color: var(--nr-text-muted);
}

/*
 * The footer part is shared by every template, but the Elsewhere
 * template sets it on burnt orange rather than ink. Its text follows the
 * surface instead of carrying the design's fixed 60% off-white, which
 * measured 1.96:1 on orange (the wordmark 3.08:1). An editor-picked
 * colour on the group or the title still wins.
 */
.nr-footer:not(.has-text-color) {
	color: var(--nr-text-muted);
}

.nr-footer .wp-block-site-title:not(.has-text-color) {
	color: var(--nr-on-surface);
}

/*
 * The artboard's card is one flex column with `gap:16px` between icon,
 * headline and description, and neither text element carries a margin or
 * a line-height of its own (so `normal`, not the root 1.65 or the heading
 * element's 1.05). render.php/edit.js put the headline and description in
 * `.nr-skill-card__content`, so that wrapper repeats the same column and
 * gap, and the UA heading/paragraph margins are zeroed — they were adding
 * 20px above the headline and 20px between it and the description.
 */
.nr-skill-card__icon {
	line-height: normal;
}

.nr-skill-card .nr-skill-card__content {
	display: flex;
	flex-direction: column;
	gap: 16px;
}

.nr-skill-card__content > * {
	margin: 0;
}

/* nr/skill-card's ink surface needs its own text colours — the artboard
   (_design-source/Nathaly Rojas.dc.html, the approved contract) sets the
   headline to off-white and the description to off-white at 60% opacity.
   Card styling is static by agreement (docs/editability-ledger.md), so
   these live here as plain CSS, not as a palette entry or a control. */
.nr-skill-card__content h3 {
	line-height: normal;
	color: var(--wp--preset--color--off-white);
	font-family: var(--wp--preset--font-family--body);
	font-size: var(--wp--preset--font-size--card-title);
	font-weight: 700;
}

.nr-skill-card__content p {
	color: rgba(245, 245, 240, 0.6);
	font-size: var(--wp--preset--font-size--body);
}

/*
 * nr/proof-card's title and blurb (artboard: title in the card's own
 * accent colour at weight 500, blurb muted ink) — both draw in the body
 * font, not the new root heading default (Playfair), since the root
 * `styles.elements.heading` in theme.json now applies to every heading
 * including this one. `--nr-accent` is set inline per instance by
 * render.php (one CSS custom property, since each card's accent is
 * chosen per block instance, not a fixed class). As on the skill card, the
 * title and blurb carry no margin (the card's own `gap:12px` is the only
 * space between them) and the title draws at line-height `normal`.
 */
.nr-proof-card > * {
	margin: 0;
}

/* Weight 700, not the artboard's 500: at 20px that makes the title large
   text under WCAG (≥18.66px bold), so its accent needs 3:1 on cream, not
   4.5:1 — rose measures 3.64:1 and burnt orange 3.13:1 (decisions-log,
   "Bold proof-card titles"). */
.nr-proof-card h3 {
	line-height: normal;
	color: var(--nr-accent);
	font-family: var(--wp--preset--font-family--body);
	font-size: var(--wp--preset--font-size--card-title);
	font-weight: 700;
}

/* The card is always cream (render.php), so its blurb takes the light
   surface's muted token: 6.20:1, where the design's 60% ink was 4.46:1. */
.nr-proof-card p {
	color: var(--text-muted-on-light);
	font-size: var(--wp--preset--font-size--body);
}

/*
 * `core/button` style variations for the three vendored Button.jsx
 * variants `theme.json`'s `styles.elements.button` does not cover
 * (Task 13 fix round 1, Finding 1). `primary` — rose fill, off-white
 * text, `--shadow-button`, hover to `rose-dark` — is that
 * `styles.elements.button` entry; these three are `secondary`, `on-dark`
 * and `highlight`, read from `_ds_bundle.js`'s `Button` component
 * (`variants/hovers` objects), never retyped from the digest.
 *
 * WordPress adds `is-style-{name}` to the block's own wrapper
 * (`.wp-block-button`), not to the inner `.wp-block-button__link` anchor —
 * confirmed via `wp.blocks.getBlockContent()` on a styled button block —
 * so every selector below targets the wrapper, then styles the anchor.
 * Border radius is already `--radius-pill` via the `a.wp-element-button`
 * rule above; these rules never redeclare it.
 */
.wp-block-button.is-style-secondary .wp-block-button__link,
.wp-block-button.is-style-on-dark .wp-block-button__link,
.wp-block-button.is-style-highlight .wp-block-button__link {
	transition: background-color var(--nr-duration) var(--nr-ease),
		color var(--nr-duration) var(--nr-ease),
		border-color var(--nr-duration) var(--nr-ease);
}

/*
 * Round 3, Finding 7: `Button.jsx`'s `variants` object gives only
 * `primary` and `highlight` a `boxShadow` — `secondary` and `on-dark` are
 * flat, borderless-of-shadow outlines. `theme.json`'s `styles.elements.
 * button` shadow (first round's fix for the *unstyled* button) targets
 * `.wp-element-button` generically, with nothing here to opt these two
 * variants back out — so they inherited the primary button's shadow.
 */
.wp-block-button.is-style-secondary .wp-block-button__link,
.wp-block-button.is-style-on-dark .wp-block-button__link {
	box-shadow: none;
}

.wp-block-button.is-style-secondary .wp-block-button__link {
	background-color: transparent;
	color: var(--wp--preset--color--ink);
	border: 2px solid var(--wp--preset--color--ink);
}

.wp-block-button.is-style-secondary .wp-block-button__link:hover,
.wp-block-button.is-style-secondary .wp-block-button__link:focus-visible {
	background-color: var(--wp--preset--color--ink);
	color: var(--wp--preset--color--off-white);
}

.wp-block-button.is-style-on-dark .wp-block-button__link {
	background-color: transparent;
	color: var(--wp--preset--color--off-white);
	border: 2px solid var(--wp--preset--color--off-white);
}

.wp-block-button.is-style-on-dark .wp-block-button__link:hover,
.wp-block-button.is-style-on-dark .wp-block-button__link:focus-visible {
	background-color: var(--wp--preset--color--off-white);
	color: var(--wp--preset--color--ink);
}

.wp-block-button.is-style-highlight .wp-block-button__link {
	background-color: var(--wp--preset--color--burnt-orange);
	color: var(--wp--preset--color--off-white);
}

.wp-block-button.is-style-highlight .wp-block-button__link:hover,
.wp-block-button.is-style-highlight .wp-block-button__link:focus-visible {
	background-color: var(--accent-highlight-hover);
	color: var(--wp--preset--color--off-white);
}

/*
 * Round 3, Finding 8: `Button.jsx` has exactly three sizes
 * (`sm`/`md`/`lg`), none of which `core/button` has any native concept
 * of — nothing here ever set any of them, so every button rendered at the
 * browser's own default padding/font-size. The artboard uses `size="lg"`
 * for every CTA on Work and Say Hi; `.nr-btn-lg` is the class those
 * buttons carry (lets-connect.php, say-hi.php) to opt into it.
 */
.wp-block-button.nr-btn-lg .wp-block-button__link {
	padding: 18px 36px;
	font-size: var(--wp--preset--font-size--body-lg);
}

/*
 * Core's own `outline` button style (registered by WordPress, not by this
 * theme), styled to follow the surface it sits on. The "Download CV"
 * synced pattern is one block shown on two backgrounds — Let's connect
 * (off-white) and Say Hi (ink) — so it cannot carry `secondary` or
 * `on-dark`: identical content has to resolve to both. At rest it is
 * `secondary` on off-white and `on-dark` on ink; on hover/focus it fills
 * with its own colour and the text takes the surface's.
 *
 * `--nr-surface` / `--nr-on-surface` name each background and the colour
 * that reads on it (tokens.css sets them per palette background). An
 * author-picked text or background colour on the button still wins — the
 * rules skip `.has-text-color` / `.has-background`. Last in the file, and
 * never below 0,4,0, so no earlier button rule out-ranks it by accident.
 */

.wp-block-button.is-style-outline .wp-block-button__link.wp-element-button {
	border: 2px solid currentcolor;
	box-shadow: none;
	transition:
		background-color var(--nr-duration) var(--nr-ease),
		color var(--nr-duration) var(--nr-ease),
		border-color var(--nr-duration) var(--nr-ease);
}

.wp-block-button.is-style-outline .wp-block-button__link:not(.has-text-color) {
	color: var(--nr-on-surface);
}

.wp-block-button.is-style-outline .wp-block-button__link:not(.has-background) {
	background-color: transparent;
}

.wp-block-button.is-style-outline .wp-block-button__link:not(.has-text-color):not(.has-background):hover,
.wp-block-button.is-style-outline .wp-block-button__link:not(.has-text-color):not(.has-background):focus-visible {
	border-color: var(--nr-on-surface);
	background-color: var(--nr-on-surface);
	color: var(--nr-surface);
}
