/*
 * Design_Tokens — the single source of colour, typography and spacing values.
 *
 * Loaded first, before base.css, because every other sheet reads these custom
 * properties and defines no colour of its own. Hand-authored: no preprocessor,
 * no build step, no third-party request.
 *
 * Three rules govern this file:
 *
 *  1. Two families, and they never mix. The *structural* blue dresses the site:
 *     the nameplate band, the rules, the headings, the links, the table head.
 *     The *status* colours say what a term is doing: green while it runs, amber
 *     when it is nearly elapsed, muted red-brown when it is exceeded. A
 *     structural colour never signals a status, and --itwt-overdue and its
 *     companions are reserved for "termijn verstreken" and used nowhere else.
 *     The token names say "overdue" so that any other use reads as a mistake in
 *     review, and so the accent-exclusivity check has something unambiguous to
 *     look for. Colour is never the only carrier: every coloured status element
 *     has the status word next to it.
 *  2. The site is light, always. Not a preference, not a toggle: an
 *     administrative record that changes appearance per device is harder to
 *     cite and harder to read.
 *  3. Every foreground/background pair below carries its measured WCAG contrast
 *     ratio as a comment. A later change to a colour must keep the number at or
 *     above the threshold written next to it.
 *
 * Measured contrast ratios (WCAG 2.x relative luminance, sRGB):
 *
 *   ink          on paper          16.17 : 1   body text, target >= 7    (22.7)
 *   ink          on paper-raised   17.65 : 1   body text on a raised surface
 *   ink          on overdue-soft   14.66 : 1   body text inside an overdue row
 *   paper        on ink-deep       16.96 : 1   text on the masthead band
 *   paper-soft   on ink-deep        9.84 : 1   secondary text on the band
 *   rule         on ink-deep        4.70 : 1   borders on the band, >= 3
 *   ink-soft     on paper           7.38 : 1   secondary text, >= 4.5
 *   ink-soft     on paper-raised    8.06 : 1
 *   ink-soft     on overdue-soft    6.70 : 1
 *   overdue      on paper           6.98 : 1   overdue label text, >= 4.5
 *   overdue      on paper-raised    7.62 : 1
 *   overdue      on overdue-soft    6.33 : 1   overdue text on its own tint
 *   overdue-ink  on overdue         7.62 : 1   text on a filled Termijnbalk
 *   rule         on paper           3.61 : 1   borders and large text, >= 3
 *   rule         on paper-raised    3.94 : 1
 *   rule         on overdue-soft    3.27 : 1
 *   rule         on brand-tint      3.37 : 1
 *   rule         on brand-deep      4.01 : 1
 *   brand        on paper          10.30 : 1   headings and section rules
 *   brand        on paper-raised   11.24 : 1
 *   brand        on brand-tint      9.60 : 1
 *   paper-raised on brand          11.24 : 1   text on the table head
 *   link         on paper           7.88 : 1   links
 *   link         on paper-raised    8.60 : 1
 *   link         on brand-tint      7.35 : 1
 *   ink          on brand-tint     15.08 : 1
 *   ink-soft     on brand-tint      6.89 : 1
 *   brand-deep   on brand-tint     13.51 : 1   shop hover on the nameplate
 *   overdue      on brand-tint      6.51 : 1
 *   ontime       on paper           5.88 : 1   a running term
 *   ontime       on paper-raised    6.42 : 1
 *   soon         on paper           6.25 : 1   a term nearly elapsed
 *   soon         on paper-raised    6.82 : 1
 *
 * The --itwt-rule value is deliberately darker than a decorative hairline grey:
 * a lighter grey looked calmer but measured 1.33 : 1 against the paper, which
 * fails the 3 : 1 floor that Requirement 22.6 sets for interface borders. The
 * requirement wins over the preference.
 *
 * That happened a second time when the palette turned warm. The restyle this
 * page now carries proposed #e6e1d8 for the rule, which is a beautiful line and
 * measures 1.11 : 1 against the warmest surface it has to sit on — the borders
 * of the Dossier table and of every form field would have been decorative
 * rather than visible. #877e72 is the warm equivalent that clears the floor on
 * all four surfaces (3.77, 3.99, 3.49 and 3.41 : 1), which is where it stays.
 *
 * Requirements: 22.1, 22.2, 22.3, 22.4, 22.5, 22.6, 22.7, 23.1, 23.2
 */

/* ---------------------------------------------------------------------------
 * Self-hosted webfonts
 *
 * woff2 only, served from assets/fonts, with font-display: swap so text is
 * readable during the font load instead of invisible. Every family token below
 * ends in a system fallback, so a missing woff2 file degrades to that fallback
 * and can never blank out a page. See assets/fonts/README.md for exactly which
 * files to download and where they come from.
 * ------------------------------------------------------------------------ */

@font-face {
	font-family: "Cormorant Garamond";
	font-style: normal;
	font-weight: 600;
	font-display: swap;
	src: url("../fonts/cormorant-garamond-600.woff2") format("woff2");
}

@font-face {
	font-family: "Inter";
	font-style: normal;
	font-weight: 400;
	font-display: swap;
	src: url("../fonts/inter-400.woff2") format("woff2");
}

@font-face {
	font-family: "Inter";
	font-style: italic;
	font-weight: 400;
	font-display: swap;
	src: url("../fonts/inter-400-italic.woff2") format("woff2");
}

@font-face {
	font-family: "Inter";
	font-style: normal;
	font-weight: 600;
	font-display: swap;
	src: url("../fonts/inter-600.woff2") format("woff2");
}

@font-face {
	font-family: "IBM Plex Mono";
	font-style: normal;
	font-weight: 400;
	font-display: swap;
	src: url("../fonts/ibm-plex-mono-400.woff2") format("woff2");
}

/* ---------------------------------------------------------------------------
 * Tokens
 * ------------------------------------------------------------------------ */

:root {
	/*
	 * Forced light appearance. Tells the browser to render its own UI (form
	 * controls, scrollbars, spellcheck underlines) in light mode only, so those
	 * parts cannot be recoloured behind the tokens below.
	 */
	color-scheme: only light;

	/* Paper and ink -------------------------------------------------------- */

	--itwt-paper: #faf8f5;              /* warm paper, the page background      */
	--itwt-paper-raised: #ffffff;       /* table rows, panels, form fields      */
	--itwt-ink: #1c1e22;                /* body text        15.75 : 1 on paper  */
	--itwt-ink-soft: #5e646e;           /* secondary text    5.62 : 1 on paper  */
	--itwt-rule: #877e72;               /* borders           3.77 : 1 on paper  */

	/* The structural blue -------------------------------------------------- */

	/*
	 * An archival blue: the colour of a bound file and a stamped form. It dresses
	 * the site — the nameplate band, the section rules, the headings, the links,
	 * the table head — and it never says anything about a status. A reader who
	 * learns that colour means "this is the site" cannot then mistake it for
	 * "this term is fine".
	 *
	 * --itwt-paper is the text colour on the deep band and --itwt-rule its
	 * border; both are tokens already in use, measured against it above.
	 */
	--itwt-brand-deep: #0f1d2b;         /* nameplate and footer band            */
	--itwt-brand: #1c3144;              /* headings         12.60 : 1 on paper  */
	--itwt-brand-tint: #f3efe9;         /* quiet surface: table head on a phone */
	--itwt-link: #194e80;               /* links             8.11 : 1 on paper   */
	--itwt-paper-soft: #b7bec3;         /* secondary text on the band, 9.07 : 1 */

	/* The status colours --------------------------------------------------- */

	/*
	 * What a term is doing, and nothing else. Never for a link, a button, a focus
	 * ring or a heading: those are structural and take the blue above.
	 *
	 * Muted red-brown is narrower still — reserved exclusively for the state
	 * "termijn verstreken". If a stylesheet outside the overdue state references
	 * one of those three tokens, that is the bug.
	 */
	--itwt-ontime: #2c6a4c;             /* a running term    6.05 : 1 on paper  */
	--itwt-soon: #7d5200;               /* nearly elapsed    6.43 : 1 on paper  */
	--itwt-overdue: #8c3a2b;            /* exceeded          7.19 : 1 on paper  */
	--itwt-overdue-soft: #f5ebe7;       /* accent tint, background only         */
	--itwt-overdue-ink: #ffffff;        /* on the accent     7.62 : 1           */

	/* Focus -------------------------------------------------------------- */

	/*
	 * Ink, not the accent: a focus ring is not an overdue term.
	 */
	--itwt-focus: #1c1e22;              /* 15.75 : 1 on paper                   */
	--itwt-focus-width: 3px;
	--itwt-focus-offset: 2px;

	/* Typefaces ---------------------------------------------------------- */

	--itwt-font-head: "Cormorant Garamond", Garamond, Georgia, "Times New Roman", serif;
	--itwt-font-body: "Inter", system-ui, -apple-system, "Segoe UI", Arial, sans-serif;
	--itwt-font-mono: "IBM Plex Mono", ui-monospace, "SFMono-Regular", Consolas, "Courier New", monospace;

	/*
	 * 600, and only 600, because that is the single heading weight in
	 * assets/fonts. Asking for 700 with no 700 file on disk makes the browser
	 * smear the 600 outlines into a fake bold, which on a Garamond is visible
	 * immediately. One weight, stated here, is what keeps that from happening.
	 */
	--itwt-weight-head: 600;
	--itwt-weight-body: 400;
	--itwt-weight-strong: 600;

	/* Type scale --------------------------------------------------------- */

	--itwt-size-body: 1.125rem;         /* 18px */
	--itwt-size-small: 1rem;            /* 16px, the floor for any text input   */
	--itwt-size-mono: 1rem;             /* kenmerken and dates                  */
	--itwt-size-label: 0.8125rem;       /* section labels only, never body text */

	/*
	 * The headings scale with the viewport between a phone and a desktop, so a
	 * page title is not the same 32px on a 360px screen as on a 1400px one. The
	 * lower bound of each clamp is the size the scale had before, so nothing
	 * gets smaller than it was.
	 */
	/*
	 * A step larger than the scale carried before, because Cormorant Garamond
	 * has a small x-height: at an identical size it reads noticeably smaller
	 * than the grotesque beside it, and a page title that has to compete with
	 * 18px body text loses. The lower bounds stay above the old ones, so no
	 * heading shrank on a phone.
	 */
	--itwt-size-lede: clamp(1.1875rem, 1.1rem + 0.35vw, 1.375rem);
	--itwt-size-h1: clamp(2.375rem, 1.7rem + 2.8vw, 3.5rem);
	--itwt-size-h2: clamp(1.6875rem, 1.45rem + 1vw, 2.25rem);
	--itwt-size-h3: 1.4375rem;

	--itwt-line-body: 1.65;

	/* A tighter leading, which a Garamond at display size can carry. */
	--itwt-line-head: 1.14;

	/*
	 * Cormorant is already narrow, so it needs far less negative tracking than
	 * the grotesque it replaced: at -0.018em the letters started to touch at
	 * display sizes. The generous positive tracking on the uppercase labels is
	 * what makes the page read as typeset rather than as default.
	 */
	--itwt-tracking-head: -0.008em;
	--itwt-tracking-label: 0.14em;

	--itwt-measure: 68ch;               /* reading measure for running text     */
	--itwt-measure-lede: 56ch;          /* shorter, so a lead paragraph reads as one */

	/* Tap targets -------------------------------------------------------- */

	--itwt-tap-min: 44px;               /* floor for every interactive element  */

	/* Spacing scale ------------------------------------------------------ */

	--itwt-space-3xs: 0.125rem;
	--itwt-space-2xs: 0.25rem;
	--itwt-space-xs: 0.5rem;
	--itwt-space-s: 0.75rem;
	--itwt-space-m: 1rem;
	--itwt-space-l: 1.5rem;
	--itwt-space-xl: 2rem;
	--itwt-space-2xl: 3rem;

	/* Rules, radii and bar geometry -------------------------------------- */

	--itwt-rule-width: 1px;
	--itwt-rule-width-strong: 2px;
	--itwt-radius: 8px;

	/* A shade rounder than the rest, for a panel that holds a whole record. */
	--itwt-radius-card: 12px;
	--itwt-radius-pill: 100px;
	--itwt-bar-height: 0.75rem;
	--itwt-page-max: 72rem;
	--itwt-page-gutter: var(--itwt-space-m);

	/* Elevation ---------------------------------------------------------- */

	/*
	 * Depth is cast in the structural blue rather than in neutral black, so a
	 * raised surface reads as part of this site and not as a generic card. The
	 * alpha stays low: a shadow here separates a panel from the paper, it does
	 * not decorate it.
	 *
	 * Every shadow value lives in this file because base.css is held to
	 * declaring no colour of its own, and an rgba() is a colour.
	 */
	--itwt-shadow-s: 0 1px 2px rgba(15, 29, 43, 0.05), 0 1px 3px rgba(15, 29, 43, 0.04);
	--itwt-shadow-m: 0 2px 8px rgba(15, 29, 43, 0.07);
	--itwt-shadow-l: 0 8px 24px rgba(15, 29, 43, 0.11);
	--itwt-shadow-band: inset 0 -1px 0 rgba(255, 255, 255, 0.08);

	/*
	 * A card at rest and a card under the pointer. Two layers each: a wide, very
	 * faint one for the lift and a tight one for the edge, which is what keeps a
	 * raised panel from looking like it is floating in front of the page.
	 */
	--itwt-shadow-card: 0 4px 20px -2px rgba(15, 29, 43, 0.05), 0 2px 6px -1px rgba(15, 29, 43, 0.04);
	--itwt-shadow-card-hover: 0 12px 32px -4px rgba(15, 29, 43, 0.09), 0 4px 12px -2px rgba(15, 29, 43, 0.05);

	/* Hairline on the dark band, where --itwt-rule would be too heavy. */
	--itwt-rule-on-band: rgba(255, 255, 255, 0.12);

	/*
	 * The play triangle on a video card that has no thumbnail. Not a status
	 * colour and not a link colour: it is the paper showing through the band.
	 */
	--itwt-play-icon: rgba(255, 255, 255, 0.55);
	--itwt-play-icon-hover: rgba(255, 255, 255, 0.85);

	/* Motion ------------------------------------------------------------- */

	/*
	 * One duration and one easing for the whole site. Short enough that a hover
	 * feels immediate; the reduced-motion rule in base.css switches every
	 * transition off, so this token is a preference and never a requirement.
	 */
	--itwt-motion: 0.18s;
	--itwt-ease: cubic-bezier(0.2, 0, 0.2, 1);
	--itwt-lift: -2px;

	/* Structural gradients ------------------------------------------------ */

	/*
	 * WHY THESE ARE SAFE
	 * Each gradient interpolates between two tokens of the *structural* blue
	 * family and never touches --itwt-ontime, --itwt-soon or --itwt-overdue. A
	 * gradient can therefore never be read as a status, which is the one thing
	 * colour on this site is not allowed to do ambiguously.
	 *
	 * Contrast is safe by construction: both endpoints of every gradient are
	 * audited pairs against the text that sits on them, so every point in
	 * between clears the same threshold.
	 */
	--itwt-gradient-band: linear-gradient(180deg, var(--itwt-brand-deep) 0%, var(--itwt-brand-deep) 100%);
	--itwt-gradient-surface: linear-gradient(180deg, var(--itwt-brand-tint) 0%, var(--itwt-paper) 100%);
	--itwt-gradient-hero: linear-gradient(108deg, var(--itwt-brand-tint) 0%, var(--itwt-brand-tint) 36%, var(--itwt-paper-raised) 100%);
	--itwt-gradient-action: linear-gradient(180deg, var(--itwt-brand) 0%, var(--itwt-brand-deep) 100%);
	--itwt-gradient-action-hover: linear-gradient(180deg, var(--itwt-link) 0%, var(--itwt-brand) 100%);
	--itwt-gradient-rule: linear-gradient(90deg, var(--itwt-brand) 0%, var(--itwt-link) 100%);
	--itwt-hatch: repeating-linear-gradient(
		-32deg,
		transparent 0,
		transparent 11px,
		rgba(14, 36, 56, 0.035) 11px,
		rgba(14, 36, 56, 0.035) 12px
	);
}

/* ---------------------------------------------------------------------------
 * Forced light appearance under a dark system preference
 *
 * Why this block exists, given that :root already declares
 * color-scheme: only light:
 *
 *   A browser, an operating system theme or a reader extension that honours the
 *   dark preference will otherwise still recolour the parts it owns — form
 *   controls, scrollbars, autofilled fields, selection highlight — and paint
 *   dark widgets onto a light page. That produces dark-on-dark text in exactly
 *   the places a contributor has to type, and it happens on the visitor's
 *   machine where no contrast audit of ours ever runs.
 *
 * So the light values are declared a second time here, at the same specificity
 * but inside the dark media query, which means the answer to
 * "prefers-color-scheme: dark" is explicitly the light palette rather than an
 * absence of instruction. The values are byte-identical to the block above on
 * purpose; if one changes there, it changes here.
 *
 * Requirements: 22.4, 22.5
 * ------------------------------------------------------------------------ */

@media (prefers-color-scheme: dark) {

	:root {
		color-scheme: only light;

		--itwt-paper: #faf8f5;
		--itwt-paper-raised: #ffffff;
		--itwt-ink: #1c1e22;
		--itwt-ink-soft: #5e646e;
		--itwt-rule: #877e72;

		--itwt-brand-deep: #0f1d2b;
		--itwt-brand: #1c3144;
		--itwt-brand-tint: #f3efe9;
		--itwt-link: #194e80;
		--itwt-paper-soft: #b7bec3;

		--itwt-ontime: #2c6a4c;
		--itwt-soon: #7d5200;
		--itwt-overdue: #8c3a2b;
		--itwt-overdue-soft: #f5ebe7;
		--itwt-overdue-ink: #ffffff;

		--itwt-focus: #1c1e22;
	}
}
