/* ==========================================================================
   Oliver Camponovo — design tokens

   Every value the site is allowed to use lives here. The rule is simple: a
   component may compose tokens, it may not invent a number. Before this file
   existed the page carried 19 font sizes, 22 letter-spacings, 8 shadows and
   5 card paddings, none of them related to one another — which is what made
   it read as a competent template rather than as a designed object.
   ========================================================================== */

:root {

  /* -- Colour scheme -----------------------------------------------------
     The page commits to one look: warm paper, warm ink, gold. There is no
     dark variant and there should not be one — the alternation of dark and
     light bands *is* the composition, and a palette that inverts under the
     reader's OS setting would invert the argument the page is making.

     Saying so out loud is the part that was missing. Without this
     declaration the browser assumes the document can do either, so it paints
     the surfaces it owns — the scrollbar, the text field's caret and
     autofill, the tap highlight — from the operating system's preference. On
     a phone set to dark that put a dark scrollbar down the side of a paper
     page and, in the enrolment modal, a dark autofill wash behind ink-dark
     text. Nothing here overrides those surfaces; this tells the browser
     which set to use. */
  color-scheme: light;

  /* -- Ink ---------------------------------------------------------------
     A warm near-black, not a neutral grey. #1a1a1a is the colour of UI
     chrome; ink on paper has a brown cast. The ramp exists so that the four
     dark sections of the page are not four identical slabs: each step is
     small enough to read as one continuous field and large enough to stop
     the page looking flat where two dark sections meet. */

  --ink-900: #0d0c0a;   /* deepest — the close of the page */
  --ink-800: #131210;   /* hero */
  --ink-700: #191714;   /* standard dark section */
  --ink-600: #1f1c18;   /* lifted dark section */
  --ink-500: #2a2620;   /* raised surfaces on dark */
  --ink: var(--ink-700);
  --ink-deep: var(--ink-900);

  /* -- Paper -------------------------------------------------------------
     Same idea in the other direction. Cards on paper lift *towards white*
     rather than being outlined, which is how printed matter behaves. */

  --paper-000: #fdfcfa;   /* raised surface */
  --paper-100: #f6f3ee;   /* standard paper */
  --paper-200: #efebe3;   /* recessed panel */
  --paper: var(--paper-100);

  /* -- Gold --------------------------------------------------------------
     --gold is the brand colour: fills, rules, decoration, and text on dark
     surfaces (7.1:1 on ink). As text on paper it reaches only 2.2:1, so
     --gold-ink is the AA-compliant equivalent (5.0:1) used for copy.
     --gold-text resolves to whichever is correct for the current surface. */

  --gold: #c5a059;
  --gold-bright: #d8bd85;   /* hairlines and accents on dark only */
  --gold-ink: #836230;      /* AA text on paper */
  --gold-dim: #9d8149;
  --gold-text: var(--gold-ink);

  --alliance: #ec4899;
  --alliance-ink: #b02566;
  --alliance-text: var(--alliance-ink);

  --danger: #ef4444;
  /* The AA-on-paper counterpart, the same relation --gold-ink has to --gold.
     --danger is a fill and a 2px rule; as 18px text on --paper-200 it measures
     3.17:1, and the exposure panel's verdict is exactly that. This value was
     already in the sheet as a literal on .enrol__error, and measures 5.44:1
     on --paper-200 and 5.85:1 on --paper-100. */
  --danger-ink: #b91c1c;
  --safe: #22c55e;

  /* The exposure panel's third verdict. Deliberately not --safe: with every
     question weighted 30 and the lower threshold at 40, `secured` covers one
     flag as well as none, so a reassuring colour would tell half the people
     who see it something their answers do not support.

     It was #8a93a3, written in oc-site.js and applied as an inline style —
     the one colour on the site that this file did not know, and at 2.60:1 on
     --paper-200 it was also unreadable. Same blue-grey, dark enough to be a
     word: 4.93:1 on --paper-200, 5.30:1 on --paper-100. There is no --slate
     to go with it because nothing fills with this; it exists only as text. */
  --slate-ink: #5c6577;

  /* -- Hairlines ---------------------------------------------------------
     Tokenised so a section can flip the whole set by redeclaring three
     variables, instead of every rule hard-coding an rgba() that happens to
     suit one background. This is what made the old sheet unmaintainable:
     rgba(245,242,237,.1) appeared 24 times and rgba(26,26,26,.05) 19 times,
     and a component could not be moved between surfaces. */

  --line:      rgba(19, 18, 16, 0.12);
  --line-soft: rgba(19, 18, 16, 0.07);
  --line-gold: rgba(197, 160, 89, 0.28);

  /* The three above are decoration. They separate and enclose, and
     decoration carries no contrast floor. This one is not decoration:
     where the line IS the control — the only mark saying "type here",
     or where a button ends — SC 1.4.11 asks 3:1 of it, and --line
     measures 1.29:1 on --paper-000. Darkening --line itself would drag
     the twenty-four dividers and card edges that use it with it, which is
     a redesign and not a fix. Same ink, at the alpha that clears the floor on all
     three papers: 3.29:1 on 000, 3.24:1 on 100, 3.19:1 on 200. Use it
     only where nothing else identifies the control — a filled button
     is identified by its fill and keeps the decorative hairline. */
  --line-control: rgba(19, 18, 16, 0.48);
  --surface:   var(--paper-000);
  --surface-2: var(--paper-200);
  --on-surface:        rgba(19, 18, 16, 0.98);
  --on-surface-muted:  rgba(19, 18, 16, 0.72);
  /* 0.62, not 0.58: at 0.58 this token measured 4.43:1 on --paper-100, which
     is under AA by a margin too small to see and too real to keep. Every
     faint label on a light surface resolves through here, so the floor is
     set once. 0.62 gives 5.06:1 on --paper-100 and 4.93:1 on --paper-200. */
  --on-surface-faint:  rgba(19, 18, 16, 0.62);

  /* --gold-ink gives 5.09:1 on --paper-100, so the ring clears the 3:1 that
     SC 1.4.11 asks of a focus indicator. The bright gold would not: 2.2:1. */
  --focus-ring: var(--gold-ink);
  --focus-halo: rgba(253, 252, 250, 0.9);

  /* -- Type --------------------------------------------------------------
     Cormorant Garamond carries the voice; Inter carries the information;
     the mono face is reserved for things that are literally data — a docket
     number, a date, a step counter, a coordinate. Before, all three were
     used interchangeably for the same job, so none of them meant anything. */

  /* Neither shipped face has a single CJK glyph: 60% of the Chinese page is
     set by whatever comes after them in these lists, so the tail is not a
     fallback there — it is the typography. The serif list names a Noto for
     the platforms that have neither Apple's nor Microsoft's face; the sans
     list did not, which left Android and Linux to whatever system-ui
     resolved to. Named on both now, in the same order: Apple, Microsoft,
     Noto, generic. */

  --serif: "Cormorant Garamond", "Songti SC", "Source Han Serif SC", "Noto Serif CJK SC", "Noto Serif SC", Georgia, serif;
  --sans: "Inter", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "Noto Sans CJK SC", "Noto Sans SC", ui-sans-serif, system-ui, sans-serif;
  --mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, monospace;

  /* A fluid scale on a ~1.25 ratio. Nothing outside it, and nothing below
     --t-micro: 12px is the floor. The page previously set its primary
     navigation at 9px and eleven other things at 8px, which is the single
     clearest tell of a template — genuinely expensive typography is never
     that small, because small type is what you resort to when the hierarchy
     is not doing the work. */

  --t-display: clamp(3rem, 7.2vw, 6.5rem);
  --t-h1:      clamp(2.5rem, 5.2vw, 4.25rem);
  --t-h2:      clamp(2rem, 3.6vw, 3rem);
  --t-h3:      clamp(1.375rem, 1.7vw, 1.625rem);
  --t-h4:      1.125rem;
  --t-lead:    clamp(1.125rem, 1.4vw, 1.3125rem);
  --t-body:    1.0625rem;
  --t-small:   0.9375rem;
  --t-micro:   0.75rem;

  --lh-display: 1.02;
  --lh-title:   1.1;
  --lh-lead:    1.55;
  --lh-body:    1.7;
  --lh-tight:   1.35;

  /* Four tracking values, not twenty-two. */
  --track-label: 0.18em;   /* eyebrows, labels, meta */
  --track-nav:   0.14em;
  --track-snug:  -0.01em;
  --track-tight: -0.025em; /* display sizes only */

  --measure: 68ch;         /* the readable maximum */
  --measure-narrow: 54ch;

  /* -- Space -------------------------------------------------------------
     A 4px-based scale. The section rhythm has three densities so that the
     page has a pulse: eleven sections at an identical 128px is not rhythm,
     it is a metronome. */

  --s-1: 4px;   --s-2: 8px;   --s-3: 12px;  --s-4: 16px;
  --s-5: 24px;  --s-6: 32px;  --s-7: 48px;  --s-8: 64px;
  --s-9: 96px;  --s-10: 128px; --s-11: 160px;

  --section:       clamp(88px, 10vw, 152px);
  --section-tight: clamp(64px, 7vw, 104px);
  --section-loose: clamp(120px, 15vw, 232px);

  --pad-card:  clamp(28px, 3vw, 44px);
  --pad-panel: clamp(32px, 3.6vw, 56px);

  /* -- Grid --------------------------------------------------------------
     One shell, one gutter, one left edge for the whole document. The old
     sheet had three (0/24px, 77px and 184px at a 1280px viewport) because
     two sections used a narrower max-width and centred it, so the eye met a
     new margin twice on the way down the page. */

  --shell: 1200px;
  --shell-narrow: 880px;
  --gutter: clamp(24px, 5vw, 80px);
  --nav-h: 72px;
  --nav-h-condensed: 60px;

  /* -- Corners -----------------------------------------------------------
     Zero. The old 2px is the most indecisive value in interface design —
     too small to read as rounded, too large to read as sharp, and it costs
     the geometry its precision. Circles stay circles. */

  --r-none: 0px;
  --r-full: 999px;

  /* -- Elevation ---------------------------------------------------------
     Three shadows, each two-layer: a tight contact shadow that anchors the
     object plus a wide ambient one that gives it air. A single-layer shadow
     is what makes a card look like a div. Dark surfaces need their own set,
     because a 6%-black shadow is invisible on #191714. */

  --shadow-sm: 0 1px 2px rgba(19, 18, 16, 0.05), 0 2px 10px -2px rgba(19, 18, 16, 0.05);
  --shadow-md: 0 2px 4px rgba(19, 18, 16, 0.05), 0 14px 36px -12px rgba(19, 18, 16, 0.13);
  --shadow-lg: 0 4px 10px rgba(19, 18, 16, 0.07), 0 36px 70px -28px rgba(19, 18, 16, 0.26);

  /* -- Motion ------------------------------------------------------------
     One easing curve for everything that moves, three durations. The old
     sheet used 0.3/0.4/0.5/0.6/0.7/1/1.2s with three different curves, so
     two adjacent elements responded to the same gesture at different rates,
     which is felt even when it is not seen. */

  --ease: cubic-bezier(0.22, 1, 0.36, 1);
  --ease-in-out: cubic-bezier(0.65, 0, 0.35, 1);
  --dur-fast: 0.18s;
  --dur: 0.32s;
  --dur-slow: 0.6s;
  --dur-image: 0.9s;

  /* Kept for compatibility with rules written against the old name. */
  --ease-out-expo: var(--ease);
}

/* -- Dark surfaces --------------------------------------------------------
   A section that paints itself dark takes the inverted token set once, here,
   and every component inside it follows without knowing where it is. That is
   the whole point of the hairline tokens above.

   `u-on-dark` is the opt-in class this was designed around, and it is not
   what carries the site: the class appears in no template, in no JavaScript
   and nowhere else in the repository, so what actually works is the list of
   nine section classes beside it — which means a new dark section has to be
   added there, the coupling the opt-in was meant to remove. It is left in
   the selector, and this comment no longer describes it as the mechanism.
   Wiring it up in the templates and dropping the list, or dropping the class,
   is a change to the design system rather than a correction to it. */

.u-on-dark,
.nav, .mobilemenu, .hero, .credstrip, .archetypes, .expertise, .pedigree,
.contact, .sitefoot, .designations, .totop {
  --gold-text: var(--gold);
  --alliance-text: var(--alliance);
  --line:      rgba(246, 243, 238, 0.12);
  --line-soft: rgba(246, 243, 238, 0.06);
  --line-gold: rgba(197, 160, 89, 0.32);
  /* 3.23:1 at its worst across the five ink tones. Declared even though
     no control is outlined on dark today: a component that moves here
     must not silently inherit the light value. */
  --line-control: rgba(246, 243, 238, 0.38);
  --surface:   var(--ink-500);
  --surface-2: var(--ink-900);
  --on-surface:        #ffffff;
  --on-surface-muted:  rgba(246, 243, 238, 0.72);
  --on-surface-faint:  rgba(246, 243, 238, 0.56);
  --focus-ring: var(--gold);              /* 7.1:1 on ink */
  --focus-halo: rgba(13, 12, 10, 0.85);
  --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.3), 0 2px 10px -2px rgba(0, 0, 0, 0.25);
  --shadow-md: 0 2px 6px rgba(0, 0, 0, 0.35), 0 16px 40px -12px rgba(0, 0, 0, 0.5);
  --shadow-lg: 0 6px 14px rgba(0, 0, 0, 0.4), 0 40px 80px -30px rgba(0, 0, 0, 0.7);
}

/* -- Chinese --------------------------------------------------------------
   Letter-spacing is a Latin device. Applied to Han characters it inserts
   half an em between every glyph, which does not read as refinement — it
   reads as broken text, and it was doing so on 35 elements of this page,
   including every eyebrow at 0.5em. Han has no italic either, so browsers
   synthesise a slant that looks like a rendering fault.

   Enumerating the affected selectors was a losing game: the first pass
   listed thirty-one and still missed ten, and every new component would
   have added another. The rule is inverted instead — on a Chinese document
   nothing is tracked and nothing is slanted, and the handful of Latin
   fragments embedded in the copy give that up. That is the right trade in
   both directions: Chinese typography does not use italics for emphasis
   either, so the Latin loses a convention its surroundings never had.

   !important, deliberately. `*:lang(zh-Hans)` scores (0,1,0) — the same as
   `.eyebrow` and less than `.insights__aside p` — so without the flag the
   override loses on source order to the very rules it exists to override.
   This is the case !important is for: one writing system opting out of a
   device that does not apply to it, across every component at once.

   `*:lang(zh-Hans)`, not `:lang(zh-Hans) *`. The two differ on exactly the case
   that now exists: the Briefing carries English titles on the Chinese page,
   tagged lang="en". The descendant form matches every element inside a Chinese
   document regardless of its own language, and would strip the tracking from
   Latin text that wants it. The `:lang()` form matches an element by its own
   computed language, so an English subtree opts itself back out. */

*:lang(zh-Hans) {
  letter-spacing: 0.02em !important;
  font-style: normal !important;
}

/* Uppercasing is also a no-op on Han, so every label loses the one cue that
   made it read as a label — and the letter-spacing that would have been the
   other one is stripped by the rule above, for the reasons argued there. The
   weight carries it instead.

   What stood here set a flat `font-weight: 500` on twelve selectors. Eleven
   of the twelve declare 600 in their own rule, and `:lang(zh-Hans) .eyebrow`
   scores (0,2,0) against `.eyebrow`'s (0,1,0), so the compensation won: the
   only thing this block had ever done was make those labels *lighter* on the
   Chinese page than on every other one. The twelfth, `.credstrip__inner`,
   declares 500, so it changed nothing. Thirty-six further selectors that
   uppercase were not listed at all — the half of this the audit names. Both
   halves have one cause: the list was written by hand and nothing measured
   it. ChineseLabelWeightTests measures it now, and the sets below are the
   only shape that satisfies it.

   The rule is one step up the ladder the sheets use — 300 → 500 → 600 → 700 —
   and never a leap. Both webfonts declare `font-weight: 300 700` in
   oc-fonts.css, so the top step is a real instance of the variable axis
   rather than a synthetic bold. Han itself comes from a system face, and
   PingFang SC stops at Semibold, so on macOS that step resolves back to 600:
   a floor on what the platform can show, not a reason to leave the label
   lighter than its English twin everywhere else.

   `X:lang(zh-Hans)`, not `:lang(zh-Hans) X`, for the reason argued seven
   lines up — and here it is not hypothetical. The language menu renders one
   link per locale, each tagged with its own lang, so the descendant form put
   the Chinese weight on the English, Italian and German links beside it.

   Three uppercasing selectors are deliberately absent. `.nav__name` and
   `.manifesto__signame` render the literal string "Oliver Camponovo", and
   `.langbar` renders EN / IT / DE / ZH. Those stay Latin on every locale, the
   capitals still do their work, and there is nothing to compensate. The test
   holds that list with a reason against each, and refuses a silent one. */

/* 300, and the inherited 400, step to 500. */
.dossier__stamp span:lang(zh-Hans),
.mobilemenu__colophon:lang(zh-Hans),
.pullquote__bg span:lang(zh-Hans),
.quiz__protocol:lang(zh-Hans),
.sitefoot__row:lang(zh-Hans),
.vindication__ghost:lang(zh-Hans) {
  font-weight: 500;
}

/* 500 steps to 600. */
.article__class:lang(zh-Hans),
.credstrip__inner:lang(zh-Hans),
.expertise__tagline:lang(zh-Hans),
.global__legend:lang(zh-Hans),
.hero__location span:lang(zh-Hans),
.hub__tag:lang(zh-Hans),
.mobilemenu__langrow a:lang(zh-Hans),
.nav__menu:lang(zh-Hans),
.pedigree__degree:lang(zh-Hans),
.pullquote__attr:lang(zh-Hans),
.vindication__source:lang(zh-Hans) {
  font-weight: 600;
}

/* 600 steps to 700 — the top of the axis, and of this ladder. */
.advisory__cta span:lang(zh-Hans),
.advisory__eyebrow:lang(zh-Hans),
.archetype__profile:lang(zh-Hans),
.article__access:lang(zh-Hans),
.authorcard__label:lang(zh-Hans),
.btn-wipe:lang(zh-Hans),
.channels__label:lang(zh-Hans),
.designations__title:lang(zh-Hans),
.dossier__court:lang(zh-Hans),
.dossier__foot a:lang(zh-Hans),
.enrol__error:lang(zh-Hans),
.enrol__eyebrow:lang(zh-Hans),
.enrol__label:lang(zh-Hans),
.enrol__scorelabel:lang(zh-Hans),
.enrol__submit:lang(zh-Hans),
.eyebrow:lang(zh-Hans),
.hero__tagline:lang(zh-Hans),
.insights__all:lang(zh-Hans),
.legal__back:lang(zh-Hans),
.legal__body h2:lang(zh-Hans),
.legal__submit:lang(zh-Hans),
.mobilemenu__langlabel:lang(zh-Hans),
.mobilemenu__protocol:lang(zh-Hans),
.modal__close span:lang(zh-Hans),
.pedigree__blocktitle:lang(zh-Hans),
.quiz__audit:lang(zh-Hans),
.quiz__skip button:lang(zh-Hans),
.skip-link:lang(zh-Hans) {
  font-weight: 700;
}
