/* =============================================================================
   Brand 2.0 design tokens
   -----------------------------------------------------------------------------
   These are the REAL Brand 2.0 values, carried in via the home redesign that was
   implemented on `fran/home-redesign-implementation` in the production repo.
   They are no longer placeholders.

   Provenance, corrected twice.

   2026-08-12, after opening the file: this header used to cite "the Figma
   Foundations page (file `Orange Loops — Home-Page`, node 1:2)". There is no
   node 1:2, so the colours here were treated as the home port's own
   measurements rather than as anything readable from Figma.

   2026-09-22, the Careers port: **there IS a Foundations page** — the designers'
   current file `v4zuHnfQeDWmJsqAyNqiDq` carries `Foundation / Colors` (node
   32:2), and it names seven colours. Six of them are exactly the values
   measured here, which retrospectively confirms the home port's eye:

       Black #000000 · Orange #FF5100 · Cloud Dancer #F0EEE9
       Secondary #D8D4C8 · Secondary dark #B0AA97 · Secondary details #4D4A41
       Grid #1C1C1C

   Only the seventh was missing, and it is now --color-grid below. So "the file
   defines no colour variables at all" — which this header used to say, and which
   CLAUDE.md used to say — is wrong for the current file.
   `docs/figma-careers-specs.md` records how to read them; `docs/figma-handoff.md`
   has the rest of the Figma provenance.

   Rule for this repo: components and pages must never hard-code a colour or a
   font size. Always reference a token from this file. That is what makes a
   rebrand a one-file change instead of a 27-file change.

   Two colour groups, and the distinction matters:

     · FIXED brand colours (--color-black / --color-orange / --color-cream …)
       never change. The home page is a designed dark composition — cream cards
       on black — so it must not invert with the OS colour scheme. It references
       these.

     · SEMANTIC colours (--color-ink / --color-surface / --color-line …) do flip
       under `prefers-color-scheme: dark`. Ordinary document pages — blog, docs,
       /design-system/ — reference these.

   Mixing the two on one element is how you get white text on a cream card.
   ========================================================================== */

:root {
	/* --- Fixed brand palette (Foundations / Colors) -------------------------- */
	--color-black: #000000; /* Black */
	--color-orange: #ff5100; /* Orange */
	--color-orange-deep: #d14300; /* darker orange, bottom of the chat bar gradient */
	--color-cream: #f0eee9; /* Cloud Dancer */
	--color-white: #ffffff;

	/* Working shades derived from the three Foundations colours. Every literal
	   the Figma home implementation used is named here, so the home page CSS
	   stays token-only. */
	--color-carbon: #14110d; /* body text on cream */
	--color-carbon-soft: #2b2721; /* secondary text on cream */
	--color-carbon-muted: #3a352d; /* card body copy on cream */
	--color-carbon-deep: #0a0a0a; /* inset panel behind a client logo */
	--color-ink-on-orange: #1a1208; /* label sitting on an orange fill */
	--color-cream-dim: #efede7; /* body text on black */
	--color-cream-dimmer: #c9c7c1; /* supporting text on black */
	--color-hairline: #b4b2ae; /* 1px borders on cream */

	/* Three more, measured off the Our Work frame (Figma uH7Mitm4GF53rGZGa6URrr,
	   node 961:4985). Read them as a set: they are the warm greys that dark
	   panels sitting on cream need, and none of them is --color-hairline or
	   --color-cream-dimmer, close as those look. */
	--color-sand: #4d4a41; /* 1.5px border on a black panel */
	--color-sand-soft: #b0aa97; /* supporting text and outline buttons on black */
	--color-sand-pale: #d8d4c8; /* decorative grid on cream; light card face */

	/* The seventh Foundations colour, read off `Foundation / Colors` (node 32:2)
	   during the Careers port. It is the stroke every dark section's rounded-
	   square lattice is drawn in — home, About Us, Our Work and Careers all use
	   it, but until now each spelled it out inside its own tile SVG. */
	--color-grid: #1c1c1c;

	--color-rule-on-cream: rgb(20 17 13 / 0.25); /* footer divider */
	--color-backdrop: rgb(0 0 0 / 0.65); /* modal scrim */

	/* INVENTED, not Brand 2.0. The design has no error state and Figma defines no
	   colour variables, so there was nothing to read this from — it was chosen
	   here, and should be replaced the moment a designer specifies one.
	   Constraints it satisfies: 6.39:1 on --color-cream (WCAG AA for body text),
	   and unmistakably red rather than a darker brand orange, which matters
	   because --color-brand-strong (#d64300) sits next to it on the same form and
	   an error must not read as a call to action.
	   It sits in the FIXED group on purpose: its only user is the contact form,
	   which is a designed cream composition and must not invert in dark mode. */
	--color-danger: #a4231a; /* form validation errors on cream */
	/* The subscribe band's error red — its field border and message. Unlike
	   --color-danger this one IS designed: sampled off Figma 2808:970 (the
	   subscribe interaction spec), where it sits on the band's black-to-orange
	   wash and the cream field. --color-danger is far too dark to read there. */
	--color-danger-on-dark: #eb2e2e;

	/* --- Semantic palette (document pages, flips in dark mode) -------------- */
	--color-brand: var(--color-orange);
	--color-brand-strong: #d64300; /* orange darkened for link text on white */
	--color-brand-subtle: #fff0e9;

	--color-ink: #14161a;
	--color-ink-muted: #565d69;
	--color-line: #e3e6ea;
	--color-surface: #ffffff;
	--color-surface-sunken: #f6f7f9;

	/* --- Typography --------------------------------------------------------- */
	/* Plus Jakarta Sans is self-hosted — @font-face lives in assets/css/fonts.css
	   (weights 400 and 700, roman and italic; nothing else is used anywhere in
	   assets/css/). Only the *names* belong in this file.

	   Eurostile is the label/eyebrow face and is now also self-hosted, Bold
	   only — --font-label is only ever used at weight 700, see the --label-*
	   shorthands below. It ships on an explicit owner decision taken after the
	   supplied files failed metadata inspection; docs/font-licences.md records
	   what was found and what the decision rests on.

	   The fallback to var(--font-sans) is load-bearing, not vestigial. Deleting
	   the @font-face in fonts.css is all it takes to back this out — the stack
	   below then resolves to the body face on its own, which is what the site
	   did before. */
	--font-sans: "Plus Jakarta Sans", ui-sans-serif, system-ui, -apple-system,
		"Segoe UI", Roboto, Helvetica, Arial, sans-serif;
	--font-label: "Eurostile", var(--font-sans);
	--font-mono: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;

	/* Scale from Foundations / Typography. The px values in the comments are
	   what the Figma tokens specify; rem is what ships. */
	/* Three steps below Label/S that the Figma home uses but Foundations does not
	   name: small outline buttons, field labels, and their mobile sizes.

	   The smallest was arrived at twice independently, from the home mobile frame
	   and from the Our Work one, which is some evidence it is the real step. On
	   Our Work it is measured rather than read: [FOOD DELIVERY]
	   [MOBILE DEVELOPMENT] is 243px wide on that frame's own render, and 10px
	   uppercase Eurostile at --ls-label is what reproduces it. The tracking stays
	   at 15% because that is a brand constant; the size is the per-context
	   choice. */
	--text-4xs: 0.625rem; /* 10 — role line on the mobile quote and case cards,
	                              and the Our Work mobile card labels */
	--text-3xs: 0.6875rem; /* 11 */
	--text-2xs: 0.75rem; /* 12 */
	--text-xs: 0.8125rem; /* 13 — Label/S */
	--text-sm: 0.875rem; /* 14 — Body/S */
	--text-md: 0.9375rem; /* 15 — Label/M */
	--text-base: 1rem; /* 16 — document body */
	--text-lg: 1.25rem; /* 20 — Body/L */
	--text-xl: 1.5rem; /* 24 — Label/L */
	--text-2xl: 1.875rem; /* 30 — Display/S */
	--text-3xl: 2.25rem; /* 36 — Display/M */
	--text-4xl: 3.4375rem; /* 55 — see the note below; NOT Display/XL */
	--text-5xl: 4rem; /* 64 — hero title, desktop only (see below) */

	/* Two steps read straight off the Our Work frame with get_variable_defs, both
	   named by Foundations and neither previously in this file. They are
	   role-named rather than fitted into the t-shirt scale above on purpose: 48
	   would have to become --text-4xl and push 55 out, and 55 is what .hero h1
	   renders at on every document page.

	   Which exposes a wider problem, now measured rather than suspected — three
	   of the sizes above disagree with the Figma styles their comments name:

	     · --text-4xl says Display/XL. Display/XL is 60, not 55.
	     · --text-2xl says Display/S.  Display/S is 32, not 30.
	     · --text-xl backs --label-l.  Label/L is 32, not 24.

	   Nothing here corrects them, because each is load-bearing on a page that was
	   measured against the value it has. Tracked in CLAUDE.md, open question "Some type tokens disagree with Figma". */
	--text-display-s: 2rem; /* 32 — Display/S, the real one */
	--text-display-xs: 1.5rem; /* 24 — Display/XS, the real one (NOT --text-xl, which that open question may move to ~30–32) */
	--text-display-blog: 2.5625rem; /* 41 — home blog section title, node 681:6514 */
	--text-display-l: 3rem; /* 48 — Display/L */
	--text-display-xl: 3.75rem; /* 60 — Display/XL, the real one */
	/* Label/Intermedio is 20, which --text-lg already is; only the composite
	   below was missing. */

	/* A mobile display step Foundations does not name. It is still a type-scale
	   value, so it belongs here and not as a literal inside a media query. There
	   used to be four (-sm-1..4, for the first home mobile frame); the home
	   design-adjustments port retired the other three, and this one survives on
	   Our Work's 1100 block — hero title and case-card stat. */
	--text-display-sm-1: 2.125rem; /* 34 */

	/* The 404 mark digits — a one-off decorative display size, /404 only. */
	--text-error-mark: 13.75rem; /* 220 — desktop */
	--text-error-mark-sm: 5.5rem; /* 88 — mobile */

	--leading-tight: 1.15;
	--leading-normal: 1.6;

	/* Letter-spacing. Figma expresses these as percentages of the font size. */
	--ls-display: -0.05em; /* -5% on every Display token … */
	--ls-hero: -0.03em; /* … except the desktop hero, which is -3% */
	--ls-label: 0.15em; /* +15% on every Label token */

	/* Composite `font:` shorthands, so a rule can set family, weight, size and
	   line-height in one declaration and stay on the scale. Pair each with its
	   matching --ls-* value. */
	/* --display-xl used to be 55/0.92 off --text-4xl and was referenced nowhere,
	   so repointing it at the real Display/XL costs nothing and stops the file
	   asserting something false. */
	--display-xl: 700 var(--text-display-xl) / 1.05 var(--font-sans);
	--display-l: 700 var(--text-display-l) / 1.05 var(--font-sans);
	--display-hero: 700 var(--text-5xl) / 1.05 var(--font-sans);
	--display-hero-sm: 700 2.5rem / 1 var(--font-sans); /* 40 — hero, mobile */
	--display-m: 700 var(--text-3xl) / 1 var(--font-sans);
	--display-s: 700 var(--text-2xl) / 1 var(--font-sans);
	--body-l: 400 var(--text-lg) / 1.6 var(--font-sans);
	--body-s: 400 var(--text-sm) / 1.5 var(--font-sans);
	--label-l: 700 var(--text-xl) / 1.3 var(--font-label);
	/* Label/L at the size Foundations actually specifies (32, not the 24 that
	   --text-xl carries — see the note above). The home page's section eyebrows
	   were re-measured against it in the design-adjustments pass. */
	--label-xl: 700 var(--text-display-s) / 1.3 var(--font-label);
	--label-int: 700 var(--text-lg) / 1.3 var(--font-label); /* Label/Intermedio, 20 */
	--label-m: 700 var(--text-md) / 1.3 var(--font-label);
	--label-s: 700 var(--text-xs) / 1.3 var(--font-label);

	/* --- Space (4px base) --------------------------------------------------- */
	--space-1: 0.25rem;
	--space-2: 0.5rem;
	--space-3: 0.75rem;
	--space-4: 1rem;
	--space-6: 1.5rem;
	--space-8: 2rem;
	--space-12: 3rem;
	--space-16: 4rem;
	--space-24: 6rem;

	/* --- Shape ------------------------------------------------------------- */
	--radius-sm: 4px;
	--radius-md: 8px;
	--radius-lg: 16px;
	--radius-pill: 999px;

	/* Named after what they wrap, because the design uses several distinct
	   large radii and "3xl" would say nothing about which one to reach for. */
	--radius-media: 16px; /* image inside a card */
	--radius-card: 28px; /* service / blog card */
	--radius-card-sm: 26px; /* same card, mobile */
	--radius-panel-inner: 34px; /* panel nested inside a bordered panel */
	--radius-panel-lg: 50px; /* case study card and the panels inside it */
	--radius-panel-lg-sm: 25px; /* those same inner panels, mobile */
	--radius-chat: 30px; /* Mr. Orange window, Figma 1735:154 */
	--radius-chat-bubble: 15px; /* a message inside it */
	--radius-panel: 40px; /* testimonial, case study, CTA band, modal */
	--radius-header: 20px; /* floating header bar */
	--radius-header-sm: 16px; /* same bar, mobile */

	/* The final CTA band's mesh fill (Figma node 681:7629): black at the top left
	   running to orange at the right, with a pale glow rising from the bottom
	   left. It lives here rather than in pages/home.css because it is six colour
	   stops, and colours do not belong in a page file. */
	--gradient-cta-band: radial-gradient(
			75% 135% at 26% 118%,
			rgb(206 214 217 / 0.9) 0%,
			rgb(150 160 166 / 0.35) 32%,
			rgb(150 160 166 / 0) 56%
		),
		linear-gradient(
			100deg,
			#07090a 0%,
			#0a0a0a 24%,
			#1c0e05 44%,
			#6a2909 62%,
			#ca4808 82%,
			var(--color-orange) 100%
		);

	/* The Services carousel panel's wash (Figma 503:6750, the block behind the
	   four service cards). Same family as the CTA band above — black on the left
	   running to orange on the right, with a pale glow rising out of the bottom
	   left corner — but a much wider panel, so the stops are its own. Fitted to
	   the frame's own render: sampled along its top edge, its bottom edge and its
	   left edge, which is the only way to read a mesh fill Figma exports as an
	   image rather than as stops. */
	--gradient-services-band: radial-gradient(
			16% 80% at 0% 100%,
			rgb(252 254 255 / 1) 0%,
			rgb(190 203 210 / 0.8) 40%,
			rgb(150 165 172 / 0) 75%
		),
		radial-gradient(
			55% 12% at 4% 100%,
			rgb(252 254 255 / 1) 0%,
			rgb(232 241 246 / 0.75) 45%,
			rgb(190 203 210 / 0) 85%
		),
		linear-gradient(
			97deg,
			#000000 0%,
			#000000 24%,
			#240d05 38%,
			#4d1c08 52%,
			#772909 65%,
			#a03508 77%,
			#c43e05 88%,
			#e04a03 100%
		);

	/* Two more members of the same mesh family as the two bands above — black at
	   one corner running to orange at the opposite one, with a pale glow rising
	   out of the bottom left. Both are from the Careers frames (905:153 /
	   1773:89) and both get their own stops rather than reusing the band's,
	   because a 61px square and a 375px portrait card cannot share a ramp that
	   was fitted to a 975px strip. */
	--gradient-step: radial-gradient(
			78% 82% at 0% 100%,
			rgb(255 255 255 / 0.95) 0%,
			rgb(222 222 216 / 0.4) 45%,
			rgb(222 222 216 / 0) 76%
		),
		linear-gradient(
			100deg,
			#000000 0%,
			#140702 32%,
			#5d2107 62%,
			#b03c06 84%,
			var(--color-orange) 100%
		);

	--gradient-role-card: radial-gradient(
			48% 34% at 2% 100%,
			rgb(252 254 255 / 0.95) 0%,
			rgb(198 208 214 / 0.45) 42%,
			rgb(198 208 214 / 0) 78%
		),
		linear-gradient(
			118deg,
			#000000 0%,
			#080808 24%,
			#361305 46%,
			#8b3007 70%,
			#d04706 89%,
			var(--color-orange) 100%
		);

	/* The Labs top zone's wash (frame 9:27), behind the hero and "things we've
	   built". Rebuilt as layered radial-gradients rather than the exported image,
	   which was a low-res rounded rectangle and showed white edge artifacts when
	   stretched. Black anchors the top left, orange the right edge, and a
	   cool-white / warm-cream glow rises from the bottom so it settles into the
	   cream section below. The two glow tints exist only in this wash. */
	--gradient-labs-wash: radial-gradient(
			66% 56% at 14% 116%,
			#edf4f7 0%,
			rgb(237 244 247 / 0.45) 34%,
			rgb(237 244 247 / 0) 62%
		),
		radial-gradient(
			56% 44% at 52% 120%,
			#ffe6cd 0%,
			rgb(255 230 205 / 0) 55%
		),
		radial-gradient(
			92% 140% at 114% 52%,
			var(--color-orange) 0%,
			rgb(255 81 0 / 0.7) 30%,
			rgb(255 81 0 / 0) 66%
		),
		radial-gradient(120% 110% at 0% -4%, var(--color-black) 0%, rgb(0 0 0 / 0) 60%);

	--shadow-md: 0 4px 16px rgb(20 22 26 / 0.08);
	/* The drop shadow under a large black card: Our Work's case cards, About's,
	   and the Labs product, open-source and note cards. Every one of those frames
	   draws the same 0 4 2 at 20% black. */
	--shadow-card: 0 4px 2px rgb(0 0 0 / 0.2);
	/* The floating header bar, both themes. Taken from the dark bar the Labs and
	   Privacy frames draw; on the cream bar it is what keeps the bar distinct
	   from a cream page (Our Work), and over black it simply disappears. */
	--shadow-header: 0 2px 6px rgb(0 0 0 / 0.2);
	/* A panel floating over the page: the header's Company submenu. */
	--shadow-popover: 0 12px 30px rgb(0 0 0 / 0.18);

	--transition: 160ms ease;

	/* --- Layout ------------------------------------------------------------ */
	--content-max: 1280px; /* content band inside the 1440 desktop frame */
	--page-gutter: 80px; /* desktop grid margin (12 col / 24px gutter) */
	--page-gutter-sm: 20px; /* mobile grid margin (4 col / 16px gutter) */
	--container-width: 72rem; /* document pages: blog, docs, design system */
	--prose-width: 40rem;

	/* Decorative rounded-square grid that runs behind the dark sections. */
	--grid-tile: 68px;
	/* The Our Work mobile frame draws the same lattice at eight tiles across a
	   392 viewport — 49.11, not a scaled 68. Its own SVG, because the stroke
	   stays 1.5px rather than scaling down with the square. */
	--grid-tile-sm: 49.11px;
	--grid-tile-team: 80px;
	--grid-tile-team-sm: 43px;

	/* The header is `position: fixed`, so <body> reserves its height. Both values
	   are the header's top offset plus its bar height. */
	--header-offset: 114px; /* 28 + 86 */
	--header-offset-sm: 79px; /* 18 + 61 */

	/* --- Stacking ----------------------------------------------------------- */
	--z-header: 50;
	--z-chat: 60;
	--z-modal: 100;
	--z-skip-link: 110; /* above everything, or it can't be reached */

	/* --- Breakpoints -------------------------------------------------------- */
	/* Custom properties can't be used inside a media query, so these are
	   documentation, not references. Handoff: desktop 1440 / tablet 768 /
	   mobile 390. The mobile cut is max-width 767px — 768 is iPad portrait,
	   which belongs to tablet. That value is also duplicated in
	   assets/js/contact-form.js (MOBILE_BP); change both together. */
}

/* Only the semantic group flips. The fixed brand palette above is deliberately
   left alone: the home page is a designed dark composition already. */
@media (prefers-color-scheme: dark) {
	:root {
		--color-ink: #f2f4f7;
		--color-ink-muted: #a2abb8;
		--color-line: #2a2f37;
		--color-surface: #101216;
		--color-surface-sunken: #171a1f;
		--color-brand-strong: #ff7a3d;
		--color-brand-subtle: #2a1a10;
		--shadow-md: 0 4px 16px rgb(0 0 0 / 0.5);
	}
}
