/*
 * The Destination File — design tokens.
 *
 * THE ONE IDEA: this is a publication, not a brochure.
 *
 * Type-led, near-achromatic, one ink colour. Every villa site in the portfolio wears
 * its own dark, pigmented, photograph-led livery; this publication has to stay
 * recognisably ITSELF in either appearance, because §1.1 requires an independent
 * publication and its credibility is the asset. What carries that identity is the
 * type (Newsreader + Public Sans, which no portfolio site uses), the single claret
 * ink and the editorial restraint — not the polarity of the ground. Polarity comes
 * from this brand's own contract per RM-STD-020; nothing here is a portfolio default.
 *
 * TWO APPEARANCES, ONE DECLARATION PER COLOUR (D-054)
 *
 * Luis's approval, 2026-09-13: dark is the appearance designed and reviewed first,
 * light is its measured alternative, and the reader's device decides until the reader
 * chooses — System is the initial setting. Each colour is declared ONCE, as
 * light-dark( light, dark ), and resolves against the element's used color-scheme:
 *
 *   :root                          follows the device   (color-scheme: light dark)
 *   :root[data-appearance="light"] the reader chose Light
 *   :root[data-appearance="dark"]  the reader chose Dark
 *
 * One declaration per colour means the two palettes cannot drift apart. The dark
 * values are NOT an inversion of the light ones — inverting measured light values
 * produces the pale-text failure mode, not a dark theme. They were measured separately
 * against the dark grounds, and every ratio is recorded inline so a later reader can
 * check the claim rather than trust it.
 *
 * `data-appearance` is written by a tiny inline script in <head> (functions.php)
 * before the first paint, so a stored choice never flashes the wrong ground. Without
 * JavaScript the site follows the device — a complete state, not a degraded one.
 *
 * @package The_Destination_File
 */

:root {

	color-scheme: light dark;

	/* ---------------------------------------------------------------------
	 * INK AND PAPER — light value first, dark second. Ratios read light / dark.
	 *
	 * The light ground is PAPER, not white; white is a surface on it. The dark
	 * ground is a warm deep charcoal, never black: pure black under warm text
	 * maximises halation, the glow astigmatic readers see around light letters.
	 *
	 * Dark body ink is held deliberately BELOW headline brightness (12.49 against
	 * 15.36). Sustained reading on a dark ground is a brightness problem before it
	 * is a contrast problem — body text at full white glows; this warm off-white
	 * reads calm for a whole article. The number is the floor, the page is the test.
	 * ------------------------------------------------------------------ */

	--tdf-paper:            light-dark( #FBFAF8, #151412 );  /* page ground */
	--tdf-paper-sunk:       light-dark( #F4F2EE, #0F0E0D );  /* recessed bands — darker than the ground in both */
	--tdf-surface:          light-dark( #FFFFFF, #1C1B18 );  /* cards, panels, menus — raised in both */

	--tdf-ink:              light-dark( #1A1A17, #DAD4C9 );  /* body copy       16.72 / 12.49 on paper */
	--tdf-ink-strong:       light-dark( #0E0E0C, #EFEAE0 );  /* headings        18.52 / 15.36 */
	--tdf-ink-muted:        light-dark( #52514B, #AEA79A );  /* meta, captions   7.63 /  7.71 — 7.12 / 7.21 on sunk and surface */

	/* ---------------------------------------------------------------------
	 * RULES
	 *
	 * Two tokens, and the difference is not cosmetic. A hairline chosen by eye
	 * fails WCAG 1.4.11; anything that BOUNDS a control uses --rule-strong.
	 * ------------------------------------------------------------------ */

	--tdf-rule:             light-dark( #E2E0DA, #302E2A );  /* decorative dividers only — never a boundary */
	--tdf-rule-strong:      light-dark( #8F8981, #706A61 );  /* structural borders  3.32 / 3.44 (1.4.11) */

	/* ---------------------------------------------------------------------
	 * ACCENT — claret, 354°, in both appearances
	 *
	 * The one hue on the site. Dark claret text does not survive a charcoal ground,
	 * so the dark value is the same hue lifted and quietened — a dusty claret that
	 * reads as ink, not as pink. Hue separation from every portfolio accent is
	 * unchanged: THV gold 39° is still the closest, 45° away.
	 * ------------------------------------------------------------------ */

	--tdf-accent:           light-dark( #8C2F39, #D7A2A8 );  /* links, rules, wayfinding   7.80 /  8.44 */
	--tdf-accent-deep:      light-dark( #6E2029, #EFC6CA );  /* hover / active            10.59 / 11.92 */
	--tdf-accent-line:      light-dark( rgb( 140 47 57 / 0.45 ), rgb( 215 162 168 / 0.5 ) );  /* link underline at rest */
	--tdf-accent-wash:      light-dark( rgb( 140 47 57 / 0.06 ), rgb( 215 162 168 / 0.1 ) );  /* :target and hover washes */
	--tdf-on-accent:        light-dark( #FBFAF8, #151412 );  /* ink ON the accent          7.80 /  8.44 */

	/* ---------------------------------------------------------------------
	 * TEXT OVER A PHOTOGRAPH — the guide opening only (D-056)
	 *
	 * The same in both appearances: the photograph is the ground there, not the
	 * page. Contrast is measured on the rendered pixels behind the text, not on a
	 * token pair, because an image is not a colour.
	 *
	 * The scrim is three stops of one warm near-black. The gradient that uses them
	 * is the only one in the system (components.css, D-055); it sits behind the
	 * text side of the photograph and is gone before the middle of the frame.
	 * ------------------------------------------------------------------ */

	--tdf-on-image:         #F7F3EC;
	--tdf-on-image-muted:   #EAE4DA;
	--tdf-scrim-strong:     rgb( 12 11 10 / 0.78 );   /* the hero band's text edge (D-074) */
	--tdf-scrim-carry:      rgb( 12 11 10 / 0.56 );   /* still carrying type at the midpoint */
	--tdf-scrim-mid:        rgb( 12 11 10 / 0.46 );   /* the hero credit's own ground */
	--tdf-scrim-none:       rgb( 12 11 10 / 0 );
	--tdf-scrim-angle:      90deg;     /* text on the left: dark at the left edge */
	--tdf-focal:            50% 50%;   /* object-position for a live object-fit crop */

	/* ---------------------------------------------------------------------
	 * THE HOMEPAGE BAND (D-076)
	 *
	 * The homepage opens on a dark band, in both appearances: as at the guide
	 * opening, the ground there belongs to the photograph, not to the page. From
	 * 62em the photograph fills the band under the scrim's near-black at 70%
	 * (Luis, 2026-09-17), which clears towards the right. Below 62em, and until the
	 * photograph loads, the band is that near-black at full strength. The search
	 * field is white on the band in both appearances. Ratios are measured on the
	 * band and on the field. Over the photograph they are measured on its own pixels
	 * (D-076).
	 * ------------------------------------------------------------------ */

	--tdf-band:             rgb( 12 11 10 );              /* on-image 17.78, on-image-muted 15.55 */
	--tdf-band-scrim:       rgb( 12 11 10 / 0.7 );        /* the shade over the band's photograph, from its left edge */
	--tdf-band-rule:        rgb( 247 243 236 / 0.34 );    /* quick-link underlines, 2.86 — decorative, never a boundary */
	--tdf-band-accent:      #D7A2A8;                      /* the claret mark on the band   9.01 */
	--tdf-band-measure:     min( 40rem, 46vw );           /* the text column from 62em */
	--tdf-field:            #FFFFFF;                      /* the search field, 19.67 against the band — its own boundary */
	--tdf-field-ink:        #1A1A17;                      /* typed text      17.44 on the field */
	--tdf-field-muted:      #52514B;                      /* placeholder, icon 7.96 on the field */

	/* ---------------------------------------------------------------------
	 * TYPE
	 *
	 * Two families, both self-hosted, both OFL (licences ship beside the files in
	 * assets/fonts/). NEVER an external font request — §18 item 16, guarded by D-026.
	 *
	 * Newsreader carries titles, headings, standfirsts and quotations: it is drawn
	 * for the screen and its optical-size axis gives large headlines finer,
	 * lighter forms than the text cut. Public Sans carries the body, navigation
	 * and metadata — a clean, open sans for long reading, per Luis's approval.
	 * Neither appears anywhere in the portfolio: six of eight villa repos resolve
	 * to Gilda Display + Outfit, so those faces would read as house livery.
	 * ------------------------------------------------------------------ */

	--tdf-font-editorial:   'Newsreader', Georgia, 'Times New Roman', serif;
	--tdf-font-ui:          'Public Sans', system-ui, -apple-system, 'Segoe UI', sans-serif;

	/* Fluid scale. clamp() so type and container scale together — the common
	 * failure is careful image scaling with body text left behind. */
	--tdf-text-display:     clamp(2.75rem, 6vw, 5rem);      /* front page / hub title */
	--tdf-text-h1:          clamp(2.25rem, 4.5vw, 3.75rem);
	--tdf-text-h2:          clamp(1.625rem, 2.6vw, 2.25rem);
	--tdf-text-h3:          clamp(1.25rem, 1.7vw, 1.5rem);
	--tdf-text-lede:        clamp(1.1875rem, 1.6vw, 1.375rem);
	--tdf-text-body:        1.125rem;    /* 18px desktop */
	--tdf-text-body-mob:    1.0625rem;   /* 17px phones — long-form reading on a phone needs the extra pixel */
	--tdf-text-body-sm:     1rem;        /* 16px — the floor for any text, and every form field (iOS zoom) */
	--tdf-text-meta:        0.9375rem;
	--tdf-text-label:       0.8125rem;

	/* Weights. Headlines sit LIGHT — the refinement is in the drawing, not the
	 * weight — and the body sits at a true regular. Dark appearance takes a little
	 * weight off everything below (see the end of this file): light-on-dark text
	 * looks heavier than the same weight dark-on-light. */
	--tdf-weight-display:   380;   /* the guide title, hub and page titles */
	--tdf-weight-heading:   440;   /* h2 */
	--tdf-weight-subhead:   540;   /* h3 — small serif needs more stroke to hold */
	--tdf-weight-body:      400;
	--tdf-weight-ui:        500;   /* navigation, labels */

	/* 1.2–1.45 is the classic band for serif text; an open sans with a tall x-height
	 * needs more air, so the body sits above it on purpose. */
	--tdf-leading-display:  1.06;
	--tdf-leading-heading:  1.18;
	--tdf-leading-body:     1.7;    /* the portfolio's calmest dark article (THV) reads at 1.8 on a 16px face */
	--tdf-leading-tight:    1.35;

	/* Letterspacing: 5–12% on caps and NOTHING on lowercase. Large display type
	 * needs negative tracking because optical spacing grows with size. */
	--tdf-tracking-display: -0.018em;
	--tdf-tracking-heading: -0.01em;
	--tdf-tracking-body:    0;
	--tdf-tracking-label:   0.09em;   /* the only place caps are used */

	/* ---------------------------------------------------------------------
	 * SPACE — a 4px base, geometric rather than arbitrary
	 * ------------------------------------------------------------------ */

	--tdf-space-3xs:        0.25rem;
	--tdf-space-2xs:        0.5rem;
	--tdf-space-xs:         0.75rem;
	--tdf-space-sm:         1rem;
	--tdf-space-md:         1.5rem;
	--tdf-space-lg:         2.25rem;
	--tdf-space-xl:         3.5rem;
	--tdf-space-2xl:        5rem;
	--tdf-space-3xl:        7.5rem;

	--tdf-section-pad:      clamp(3rem, 7vw, 6.5rem);
	--tdf-section-pad-tight: clamp(2rem, 4vw, 3.5rem);

	/* ---------------------------------------------------------------------
	 * MEASURE AND GRID
	 *
	 * --measure is the most important number in the file: the article column,
	 * sized for 66–72 characters of BODY text per line. It was re-measured when
	 * the body moved from Newsreader to Public Sans (a wider face), 2026-09-13.
	 *
	 * Expressed in rem, NOT ch, and that is load-bearing (D-046). `ch` resolves
	 * against the font of the element that USES the token, so a ch measure on an
	 * h2 escapes the column while paragraphs stay inside it.
	 * ------------------------------------------------------------------ */

	--tdf-measure:          38rem;    /* article body — never wider: ~71 characters of 18px Public Sans */
	--tdf-measure-narrow:   34rem;    /* pull quotes, standfirsts */
	--tdf-measure-wide:     52rem;    /* lists, tables inside an article */

	--tdf-container:        1200px; /* editorial container */
	--tdf-container-wide:   1440px; /* full-bleed-adjacent galleries */
	--tdf-gutter:           clamp(1.25rem, 4vw, 2.5rem);
	--tdf-grid-gap:         clamp(1.5rem, 2.5vw, 2.25rem);

	/* ---------------------------------------------------------------------
	 * GEOMETRY
	 *
	 * Radius is nearly flat. Sharp edges signal precision; a rounded card reads as
	 * a SaaS tile, and a pill reads as a chip in an app.
	 * ------------------------------------------------------------------ */

	--tdf-radius:           2px;
	--tdf-radius-media:     0;      /* editorial images are square-cornered */
	--tdf-border:           1px;
	--tdf-border-heavy:     2px;

	/* ---------------------------------------------------------------------
	 * ASPECT RATIOS
	 *
	 * The R2 hero and card values mirror the §13.1 rendition set exactly. The
	 * WordPress-media hero is cropped live from ONE original (D-056): the natural
	 * 3:2 below the wide breakpoint, a wide band above it.
	 * ------------------------------------------------------------------ */

	--tdf-ratio-hero:       16 / 9;    /* R2 hero        2400x1350 */
	--tdf-ratio-hero-mob:   4 / 5;     /* R2 hero-mobile 1200x1500 */
	--tdf-ratio-hero-media: 3 / 2;     /* WordPress-media hero below the wide breakpoint */
	--tdf-ratio-opening:    21 / 9;    /* the wide-screen guide opening band */
	--tdf-ratio-card:       4 / 3;     /* card-lg / card / thumb */
	--tdf-ratio-square:     1 / 1;     /* square      800x800   */

	/* ---------------------------------------------------------------------
	 * MOTION
	 *
	 * Short, few, and never decorative. Motion only confirms an interaction the
	 * reader initiated: no scroll-scrub, no parallax, no entrance choreography.
	 * ------------------------------------------------------------------ */

	--tdf-ease:             cubic-bezier(0.2, 0, 0.2, 1);
	--tdf-duration:         160ms;
	--tdf-duration-slow:    240ms;

	/* Focus is a design element, not an afterthought. 3:1 minimum in both
	 * appearances (the accent is 7.80 / 8.44), and the offset keeps the ring off
	 * the glyphs so it stays legible on dense type. */
	--tdf-focus-width:      2px;
	--tdf-focus-offset:     3px;
	--tdf-focus-color:      var(--tdf-accent);
}

/* The reader's explicit choice pins the scheme; with no choice :root follows the device. */
:root[data-appearance="light"] {
	color-scheme: light;
}

:root[data-appearance="dark"] {
	color-scheme: dark;
}

/*
 * DARK WEIGHTS — the only values light-dark() cannot express, because they are not
 * colours. Declared twice: once for "the device is dark and the reader has not chosen
 * Light", once for "the reader chose Dark". bin/check-design-tokens.php fails the
 * build if the two blocks ever differ.
 */
@media ( prefers-color-scheme: dark ) {

	:root:not( [data-appearance="light"] ) {
		--tdf-weight-display:   360;
		--tdf-weight-heading:   420;
		--tdf-weight-subhead:   510;
		--tdf-weight-body:      380;
	}
}

:root[data-appearance="dark"] {
	--tdf-weight-display:   360;
	--tdf-weight-heading:   420;
	--tdf-weight-subhead:   510;
	--tdf-weight-body:      380;
}

/*
 * A browser without light-dark() (before Safari 17.5 / Chrome 123 / Firefox 120)
 * would discard every colour above and paint browser defaults. It gets the light
 * palette instead — measured, complete, and exactly the first argument of each
 * light-dark() pair; bin/check-design-tokens.php fails if they drift.
 */
@supports not ( color: light-dark( #000, #fff ) ) {

	:root {
		--tdf-paper:            #FBFAF8;
		--tdf-paper-sunk:       #F4F2EE;
		--tdf-surface:          #FFFFFF;
		--tdf-ink:              #1A1A17;
		--tdf-ink-strong:       #0E0E0C;
		--tdf-ink-muted:        #52514B;
		--tdf-rule:             #E2E0DA;
		--tdf-rule-strong:      #8F8981;
		--tdf-accent:           #8C2F39;
		--tdf-accent-deep:      #6E2029;
		--tdf-accent-line:      rgb( 140 47 57 / 0.45 );
		--tdf-accent-wash:      rgb( 140 47 57 / 0.06 );
		--tdf-on-accent:        #FBFAF8;
	}
}

@media ( prefers-reduced-motion: reduce ) {

	:root {
		--tdf-duration:      1ms;
		--tdf-duration-slow: 1ms;
	}
}
