/* =============================================================================
   Tokens — informal, v0.1
   Carried over from the smart-home sheet (Figma node 1:407), pruned to what a
   one-page designer portfolio actually renders. See data/portfolio-carryover.json.

   Everything here is a CSS custom property so it can be retargeted later
   without touching component markup.
   ========================================================================== */

/* Neue Montreal @font-face. These MUST sit at the top level of the
   stylesheet — an @font-face nested inside :root is invalid and is
   silently dropped, which makes the family fall back with no console
   error. Order matters only in that Regular resolves first. */
@font-face {
  font-family: "Neue Montreal";
  src: url("fonts/NeueMontreal-Regular.otf") format("opentype");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Neue Montreal";
  src: url("fonts/NeueMontreal-Italic.otf") format("opentype");
  font-weight: 400;
  font-style: italic;
  font-display: swap;
}
@font-face {
  font-family: "Neue Montreal";
  src: url("fonts/NeueMontreal-Light.otf") format("opentype");
  font-weight: 300;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Neue Montreal";
  src: url("fonts/NeueMontreal-LightItalic.otf") format("opentype");
  font-weight: 300;
  font-style: italic;
  font-display: swap;
}
@font-face {
  font-family: "Neue Montreal";
  src: url("fonts/NeueMontreal-Medium.otf") format("opentype");
  font-weight: 500;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Neue Montreal";
  src: url("fonts/NeueMontreal-MediumItalic.otf") format("opentype");
  font-weight: 500;
  font-style: italic;
  font-display: swap;
}
@font-face {
  font-family: "Neue Montreal";
  src: url("fonts/NeueMontreal-Bold.otf") format("opentype");
  font-weight: 700;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Neue Montreal";
  src: url("fonts/NeueMontreal-BoldItalic.otf") format("opentype");
  font-weight: 700;
  font-style: italic;
  font-display: swap;
}

:root {
  /* --- Colour -------------------------------------------------------------
     Strictly monochrome. Grey is a *disabled* colour, not a muted-text colour:
     the source system expresses disabled state by swapping black -> grey
     rather than by lowering opacity. */
  --c-bg: #ffffff;
  --c-fg: #000000;
  --c-disabled: #cacaca;
  --c-muted: #767676; /* NEW: mid grey for meta text. The source system had no
                         muted text colour, which a portfolio does need. */

  /* --- Border weight ------------------------------------------------------
     Weight carries emphasis, since colour is unavailable. Collapsed from the
     source's 1/2/4/5px to three steps that mean something. */
  --bw-hairline: 1px;
  --bw-base: 2px;
  --bw-heavy: 4px;

  /* --- Elevation ----------------------------------------------------------
     The hard offset shadow is the signature of the source language. Kept
     exactly. The source used only one elevation, so v0.1 does too. */
  --shadow: 6px 6px 0 0 var(--c-fg);
  --shadow-lift: 2px 2px 0 0 var(--c-fg); /* NEW: pressed/near state */

  /* --- Shape --------------------------------------------------------------
     Pill. The portfolio mockup uses fully-rounded buttons; this SUPERSEDES the
     square rule inherited from the smart-home sheet, which is not this
     project's identity. --radius stays as a 0 hook for square-edged surfaces
     (cards, fields, media) so the two can coexist. */
  --radius: 0;
  --radius-pill: 999px;

  /* --- Type ---------------------------------------------------------------
     The mockup's face is Neue Montreal (Pangram Pangram). The real files now
     live in system/fonts/ and are declared below, so the design renders in the
     intended face rather than a substitute.

     LICENSING: these are the free trial files, which Pangram Pangram permits
     for personal, non-commercial use — explicitly including personal
     portfolios and client pitches. Commercial/client work requires a paid Web
     License (~$30/family, sold separately from Desktop). See
     system/README.md > Typography before shipping to a client.

     WEIGHT RANGE: the pack ships Light 300 / Regular 400 / Medium 500 /
     Bold 700. There is NO 900, so --fw-black is mapped to Bold below — do not
     reintroduce a 900 value, which the browser would fake by smearing Bold. */
  --font: "Neue Montreal", Archivo, "Helvetica Neue", Helvetica, Arial, sans-serif;
  --font-display: var(--font);

  /* Editorial ramp, sized for a one-pager rather than an app UI.
     --fs-hero and --fs-index are deliberately oversized: the display/index
     contrast is the core visual device of the mockup.

     --fs-hero's middle term is a MIN of two rates: the editorial 9vw, and the
     0.85 rate at which the longest headline line ("DESIGNER", 15 chars) still
     fits the narrow column.

     WHY THE CAP EXISTS. 9vw grows ~11% faster than the column does, so a plain
     9vw wrapped the headline to THREE lines everywhere from ~540px up to the
     64rem breakpoint. The third line then ran straight through the scroll cue
     beneath it, which is the collision this cap removes. (The cue is not the
     vulnerable party and the fix is deliberately NOT "move the cue": the real
     fault is that the headline stopped fitting its box. Any zero-height flex
     gap on the cue is also inert, because a grid item is never stretched by an
     auto row — the wrapped line simply painted over a box it could not move.)

     0.85 is the measured width of "DESIGNER" at 1em (7.37em) plus its -0.02em
     tracking, i.e. 7.52em, over 8.85 (the em-to-vw ratio) — rounded up, so the
     cap lands with ~1.5% of slack at the tightest width. */
  --fs-hero-cap: calc(0.85 * var(--col-narrow));
  --fs-hero-ramp: 9vw;
  --fs-hero: clamp(2.75rem, 9vw, 7.5rem);
  --fs-index: clamp(4rem, 12vw, 8rem);      /* 64 -> 128px, the 01-04 numerals */
  --fs-display: clamp(2rem, 5vw, 3.5rem);
  --fs-h2: 1.5rem;
  --fs-body: 1rem;   /* floor: never go below 16px */
  --fs-meta: 0.875rem;

  --fw-regular: 400;
  --fw-bold: 700;
  /* Neue Montreal's heaviest shipped weight is Bold. Mapping the "black" role
     onto 700 is deliberate: 900 has no file, so the browser would synthesise
     it by smearing Bold, which looks like a rendering fault. --fw-black is kept
     as a distinct *role* (the loudest heading step) even though its value now
     equals --fw-bold. */
  --fw-black: 700;

  --lh-tight: 1.1;
  --lh-normal: 1.5;

  /* --- Space --------------------------------------------------------------
     4px base. The source system had ad-hoc spacing (7px, 11px, 13px, 149px);
     this replaces it with one scale. */
  --s-1: 0.25rem;
  --s-2: 0.5rem;
  --s-3: 0.75rem;
  --s-4: 1rem;
  --s-5: 1.5rem;
  --s-6: 2rem;
  --s-7: 3rem;

  /* --- Layout -------------------------------------------------------------
     The mockup is a 1440 frame with ~66px side inset, and deliberately lets
     the hero headline and the rules BREAK OUT of that container. Those two
     widths are kept separate on purpose — do not collapse them. */
  --measure: 82rem;   /* ~1312px content column */
  --measure-full: 90rem; /* ~1440px the full-bleed band for rules */
  --pad-page: var(--s-5);

  /* The narrow regime's column: the viewport minus both page insets. The hero
     headline's cap (--fs-hero, below) is derived from it. */
  --col-narrow: calc(100vw - 2 * var(--pad-page));

  /* --- Sticky header ------------------------------------------------------
     --header-h mirrors the rendered .header height and is the single source of
     truth for anything that has to clear it. It is a FALLBACK only: a build can
     measure the live header and overwrite --header-offset at runtime, so a
     stale number here cannot leave anchors hidden under the header.
     Keep it roughly in step with the rendered header: the wide layout is one
     44px pill row, the narrow one stacks the pills under the name. */
  --header-h: 8.9375rem;     /* 143px: legacy worst case (the old three-row
                                narrow header, kept as a conservative fallback) */
  --header-offset: calc(var(--header-h) + var(--s-2));
}

@media (min-width: 48rem) {
  :root {
    --header-h: 5.1875rem;   /* 83px: legacy one-row fallback (the rendered
                                header is 69px since the nav became pills) */
    --pad-page: 4rem; /* ~66px, matching the mockup inset */
    /* --pad-page just changed, so the column has to be restated for the cap. */
    --col-narrow: calc(100vw - 2 * var(--pad-page));
  }
}

/* Above 64rem the hero puts the copy and the portrait BESIDE the headline
   instead of beneath it, so the headline may grow back to the full editorial
   9vw — it is no longer sharing the column with anything, and the cue below is
   cleared by the copy row rather than by the headline. The cap is lifted here
   and only here, which is what keeps desktop at its full 120px. */
@media (min-width: 64rem) {
  :root {
  }
}
