/* Self-hosted faces (D11, D12): the same families and weights the design bundle
   loads from Google Fonts, as Fontsource WOFF2 files. Files, origins and licences
   are listed in src/assets.ts. This is the one token file that is not a copy of
   the bundle's: its tokens/fonts.css loads the faces from Google Fonts. */
@font-face { font-family: 'Outfit'; font-style: normal; font-weight: 400; font-display: swap; src: url(/assets/fonts/outfit/outfit-latin-400-normal.71f028fd.woff2) format('woff2'); }
@font-face { font-family: 'Outfit'; font-style: normal; font-weight: 500; font-display: swap; src: url(/assets/fonts/outfit/outfit-latin-500-normal.fc9bff94.woff2) format('woff2'); }
@font-face { font-family: 'Outfit'; font-style: normal; font-weight: 600; font-display: swap; src: url(/assets/fonts/outfit/outfit-latin-600-normal.8cfe15c2.woff2) format('woff2'); }
/* The serif is CF Serif: Source Serif 4, trimmed and renamed by scripts/fonts/trim-fonts.py (see
   NOTICE.txt next to the files). Every page asks for weight 400 and no other, so the roman has its
   weight pinned there and keeps its optical-size axis (8–60): the browser picks the optical size from
   the font size (font-optical-sizing: auto, the default). The italic is a static face, at optical size 18.
   The CSS family name stays 'Source Serif 4', which is what the copied tokens ask for. */
@font-face { font-family: 'Source Serif 4'; font-style: normal; font-weight: 400; font-display: swap; src: url(/assets/fonts/source-serif-4/cf-serif-roman.3c5be171.woff2) format('woff2'); }
@font-face { font-family: 'Source Serif 4'; font-style: italic; font-weight: 400; font-display: swap; src: url(/assets/fonts/source-serif-4/cf-serif-italic.f0c1a343.woff2) format('woff2'); }
/* The mono is CF Mono: IBM Plex Mono, subset to the space, A–Z, 0–9 and what the pages set in mono,
   and renamed, by the same script. The CSS family name stays 'IBM Plex Mono', as the tokens have it.
   Weight 400 only: every mono rule is the regular weight, and nothing ships that is not used. */
@font-face { font-family: 'IBM Plex Mono'; font-style: normal; font-weight: 400; font-display: swap; src: url(/assets/fonts/ibm-plex-mono/cf-mono-400.370358fc.woff2) format('woff2'); }

:root {
  /* Ground & surfaces — warm near-black, from the leather of the render */
  --cf-ground: #16130f;
  --cf-ground-deep: #100e0b;
  --cf-surface: #1f1b16;
  --cf-surface-hover: #241f19;
  --cf-surface-raised: #2c261f;
  --cf-art-backdrop: #0d1a1e;        /* behind game art. Not in the bundle's tokens: its components.css has this value raw */

  /* Lines */
  --cf-line: #2e2821;
  --cf-line-strong: #3a332a;
  --cf-line-control: #4a4234;
  --cf-line-dashed: #5a5142;
  --cf-line-teal: #2f5a54;

  /* Text — warm off-whites */
  --cf-text: #eee8de;
  --cf-text-2: #c9c0b2;
  --cf-text-3: #a89e8f;
  --cf-text-4: #8f8676;      /* mono labels, captions — still AA on ground */
  --cf-text-workshop: #b9afa0;
  --cf-text-workshop-title: #e3dccf;  /* not in the bundle's tokens: its components.css has this value raw */

  /* Metal — champagne silver from the tower */
  --cf-champagne: #d9c7a5;
  --cf-champagne-hover: #e8d9bd;
  --cf-champagne-dim: #bcae94;

  /* Glass arcs — outer (1) to inner (4) */
  --cf-arc-1: #3fb8ab;
  --cf-arc-2: #62cabd;
  --cf-arc-3: #8edbd1;
  --cf-arc-4: #c3eee8;
  --cf-arc-mid: #6fd0c4;     /* 3-arc size step */
  --cf-arc-pale: #a9e6de;    /* 2-arc size step */
  --cf-arc-off: #2a3431;     /* unlit arc, before animation */
  --cf-teal: #5ccfc1;

  /* Placeholder stripes */
  --cf-stripe-a: #1c1813;
  --cf-stripe-b: #231e18;

  /* ---- Semantic aliases ---- */
  --surface-page: var(--cf-ground);
  --surface-card: var(--cf-surface);
  --surface-card-hover: var(--cf-surface-hover);
  --surface-selected: var(--cf-surface-raised);
  --border-subtle: var(--cf-line);
  --border-control: var(--cf-line-control);
  --text-body: var(--cf-text);
  --text-secondary: var(--cf-text-2);
  --text-muted: var(--cf-text-3);
  --text-caption: var(--cf-text-4);
  --text-display: var(--cf-champagne);
  --link: var(--cf-text);
  --link-hover: var(--cf-teal);
  --link-inline: var(--cf-teal);
  --focus-ring: var(--cf-teal);
  --action-primary-bg: var(--cf-champagne);
  --action-primary-bg-hover: var(--cf-champagne-hover);
  --action-primary-fg: var(--cf-ground);

  /* Stage identity (always paired with icon + word) */
  --stage-released: var(--cf-teal);
  --stage-released-border: var(--cf-line-teal);
  --stage-soon: var(--cf-champagne);
  --stage-soon-border: var(--cf-line-control);
  --stage-workshop: #b3a998;
  --stage-workshop-border: var(--cf-line-dashed);
}

:root {
  --font-sans: 'Outfit', ui-sans-serif, system-ui, sans-serif;     /* UI, headings, wordmark */
  --font-serif: 'Source Serif 4', Georgia, serif;                  /* reading text, card lines */
  --font-mono: 'IBM Plex Mono', ui-monospace, monospace;           /* modem touches ONLY */

  --weight-regular: 400;
  --weight-medium: 500;
  --weight-semibold: 600;

  /* Desktop scale */
  --type-display-size: 76px;   --type-display-lh: 1.02;  --type-display-track: -0.02em;
  --type-h1-size: 48px;        --type-h1-lh: 1.1;
  --type-h2-size: 36px;        --type-h2-lh: 1.1;        --type-h2-track: -0.01em;
  --type-h3-feature-size: 34px;
  --type-h3-size: 28px;        --type-h3-lh: 1.15;
  --type-h3-workshop-size: 24px;
  --type-lead-size: 21px;      --type-lead-lh: 1.5;      /* serif */
  --type-body-size: 18px;      --type-body-lh: 1.5;      /* serif */
  --type-prose-size: 19px;     --type-prose-lh: 1.65;    /* serif, long-form */
  --type-ui-size: 15px;
  --type-button-size: 16px;
  --type-badge-size: 13px;
  --type-caption-size: 13px;
  --type-mono-size: 13px;      --type-mono-track: 0.08em;

  /* Wordmark */
  --wordmark-track: 0.08em;
  --wordmark-games-track: 0.44em;
}
@media (max-width: 720px) {
  :root {
    --type-display-size: 40px;  --type-display-lh: 1.05;
    --type-h1-size: 34px;
    --type-h2-size: 28px;
    --type-h3-feature-size: 26px;
    --type-h3-size: 24px;
    --type-h3-workshop-size: 22px;
    --type-lead-size: 17px;
    --type-body-size: 17px;
    --type-prose-size: 17px;
  }
}

:root {
  --space-4: 4px;   --space-6: 6px;   --space-8: 8px;   --space-10: 10px;
  --space-12: 12px; --space-14: 14px; --space-16: 16px; --space-18: 18px;
  --space-20: 20px; --space-24: 24px; --space-28: 28px; --space-32: 32px;
  --space-36: 36px; --space-40: 40px; --space-48: 48px; --space-56: 56px;
  --space-64: 64px; --space-72: 72px; --space-112: 112px; --space-128: 128px;

  --radius-control: 6px;   /* buttons, tiles */
  --radius-card: 8px;      /* cards, panels */
  --radius-pill: 999px;    /* badges, language switcher */

  --border-width: 1px;

  --page-max: 1240px;
  --gutter: 56px;
  --section-gap: 112px;    /* between stage groups */
  --hero-pad-top: 112px;
  --hero-pad-bottom: 128px;
  --tap-min: 44px;
}
@media (max-width: 720px) {
  :root {
    --gutter: 16px;
    --section-gap: 64px;
    --hero-pad-top: 56px;
    --hero-pad-bottom: 72px;
  }
}

:root {
  /* Hero: arcs light inside-out, then the lamp. Plays once. */
  --motion-arc-fade: 0.45s;
  --motion-arc-first: 0.3s;
  --motion-arc-step: 0.4s;
  --motion-lamp-delay: 1.95s;
  --motion-lamp-fade: 0.3s;
  /* 404: the lamp tries five times, the inner arc twice, then both stay dark. Plays once.
     The sequence itself is the two cf-nocarrier keyframes in site.css, in
     steps of 2.5% of this duration (0.06 s). Not in the bundle: added in task 02. */
  --motion-nocarrier-duration: 2.4s;
  --motion-hover: 120ms;
  --ease-standard: cubic-bezier(0.2, 0.7, 0.2, 1);
}

html { color-scheme: dark; }
body {
  margin: 0;
  background: var(--surface-page);
  color: var(--text-body);
  font-family: var(--font-sans);
  -webkit-font-smoothing: antialiased;
}
a { color: var(--link); }
a:hover { color: var(--link-hover); }
:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 3px; border-radius: 2px; }
::selection { background: var(--cf-line-teal); color: var(--cf-text); }
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: 0.001ms !important; animation-delay: 0s !important; transition-duration: 0.001ms !important; }
}

/* ===== Tower mark ===== */
@keyframes cf-lit { from { opacity: 0; } to { opacity: 1; } }
.cf-mark { display: block; flex: none; }
.cf-mark--animate .cf-mark__lit { animation: cf-lit var(--motion-arc-fade) linear both; }
.cf-mark--animate .cf-mark__dot { animation: cf-lit var(--motion-lamp-fade) linear var(--motion-lamp-delay) both; }
@media (prefers-reduced-motion: reduce) {
  .cf-mark--animate .cf-mark__lit, .cf-mark--animate .cf-mark__dot { animation: none; opacity: 1; }
}

/* ===== Lockup ===== */
.cf-lockup { display: inline-flex; align-items: center; gap: 12px; text-decoration: none; color: inherit; min-width: 0; }
.cf-lockup .cf-mark { width: 36px; height: 36px; }
.cf-lockup__words { display: flex; flex-direction: column; line-height: 1; min-width: 0; }
.cf-lockup__name { font: var(--weight-semibold) 17px/1 var(--font-sans); letter-spacing: var(--wordmark-track); color: var(--cf-champagne); white-space: nowrap; }
.cf-lockup__games { font: var(--weight-medium) 10px/1 var(--font-sans); letter-spacing: var(--wordmark-games-track); color: var(--text-muted); margin-top: 5px; }
.cf-lockup__words--long { line-height: 1.15; }
.cf-lockup__long1 { font: var(--weight-semibold) 16px/1.15 var(--font-sans); color: var(--cf-champagne); }
.cf-lockup__long2 { font: var(--weight-regular) 12px/1.3 var(--font-sans); color: var(--text-muted); }
.cf-lockup--stacked { flex-direction: column; gap: 28px; text-align: center; }
.cf-lockup--stacked .cf-mark { width: auto; height: auto; }
.cf-lockup--stacked .cf-lockup__words { align-items: center; }
.cf-lockup--stacked .cf-lockup__name { font-size: 52px; letter-spacing: 0.06em; }
.cf-lockup--stacked .cf-lockup__games { font-size: 20px; letter-spacing: 0.5em; padding-left: 0.5em; margin-top: 12px; color: var(--cf-champagne-dim); }
.cf-lockup--wordmark { gap: 0; }

/* ===== Language switcher ===== */
.cf-lang { display: flex; align-items: center; padding: 3px; border: 1px solid var(--cf-line-strong); border-radius: var(--radius-pill); }
.cf-lang__opt { padding: 6px 14px; border-radius: var(--radius-pill); font: var(--weight-regular) 14px/1.2 var(--font-sans); color: var(--text-muted); text-decoration: none; transition: color var(--motion-hover); }
.cf-lang__opt[aria-current="true"] { background: var(--surface-selected); color: var(--text-body); }
a.cf-lang__opt:hover { color: var(--text-body); }

/* ===== Header ===== */
.cf-header { position: relative; display: flex; align-items: center; justify-content: space-between; gap: var(--space-24); padding: 18px var(--gutter); border-bottom: 1px solid var(--border-subtle); background: var(--surface-page); }
.cf-header__nav { display: flex; align-items: center; gap: 36px; }
.cf-header__links { display: flex; align-items: center; gap: 36px; }
.cf-navlink { font: var(--weight-regular) var(--type-ui-size)/1.2 var(--font-sans); color: var(--link); text-decoration: none; transition: color var(--motion-hover); }
.cf-navlink:hover { color: var(--link-hover); }
.cf-navlink[aria-current="page"] { color: var(--cf-champagne); text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 7px; }
.cf-menu-btn { display: none; flex-direction: column; justify-content: center; gap: 5px; width: var(--tap-min); height: var(--tap-min); padding: 0 12px; background: none; border: 0; cursor: pointer; box-sizing: border-box; }
.cf-menu-btn span { display: block; height: 1.5px; background: var(--text-body); }
.cf-menu { display: none; }
@media (max-width: 720px) {
  .cf-header { padding: 10px 12px 10px 16px; gap: var(--space-8); }
  .cf-header .cf-lockup { gap: 9px; }
  .cf-header .cf-lockup .cf-mark { width: 30px; height: 30px; }
  .cf-header .cf-lockup__name { font-size: 13px; letter-spacing: 0.07em; }
  .cf-header .cf-lockup__games { font-size: 8px; margin-top: 4px; }
  .cf-header .cf-lockup__long1 { font-size: 13px; }
  .cf-header .cf-lockup__long2 { font-size: 10.5px; }
  .cf-header__nav { gap: 4px; }
  .cf-header__links { display: none; }
  .cf-header .cf-lang__opt[aria-current="true"] { display: none; }
  .cf-header .cf-lang__opt { padding: 0 9px; height: 30px; display: flex; align-items: center; }
  .cf-menu-btn { display: flex; }
  .cf-menu[data-open="true"] { display: flex; flex-direction: column; position: absolute; top: 100%; left: 0; right: 0; z-index: 10; padding: 8px 16px 16px; background: var(--surface-page); border-bottom: 1px solid var(--border-subtle); }
  .cf-menu .cf-navlink { display: flex; align-items: center; min-height: 48px; font-size: 17px; border-bottom: 1px solid var(--border-subtle); }
}

/* ===== Footer ===== */
.cf-footer { border-top: 1px solid var(--border-subtle); }
.cf-footer__inner { display: flex; justify-content: space-between; align-items: flex-start; gap: 40px; flex-wrap: wrap; max-width: var(--page-max); margin: 0 auto; padding: 48px var(--gutter) 56px; }
.cf-footer__brand { display: flex; flex-direction: column; gap: 16px; }
.cf-footer__name { display: flex; align-items: center; gap: 10px; font: var(--weight-medium) 15px/1.2 var(--font-sans); color: var(--cf-champagne); }
.cf-footer__name .cf-mark { width: 28px; height: 28px; }
.cf-footer__line { margin: 0; font: var(--weight-regular) 16px/1.5 var(--font-serif); color: var(--text-muted); }
.cf-footer__nav { display: flex; flex-wrap: wrap; gap: 4px 28px; }
.cf-footer__nav a { display: flex; align-items: center; min-height: var(--tap-min); font: var(--weight-regular) 15px/1.2 var(--font-sans); color: var(--text-secondary); text-decoration: none; }
.cf-footer__nav a:hover { color: var(--link-hover); }
@media (max-width: 720px) { .cf-footer__inner { flex-direction: column; gap: 20px; padding: 32px var(--gutter) 40px; } .cf-footer__nav { gap: 4px 20px; } }

/* ===== Buttons ===== */
.cf-btn { display: inline-flex; align-items: center; justify-content: center; gap: 8px; min-height: 48px; padding: 0 20px; box-sizing: border-box; border: 1px solid transparent; border-radius: var(--radius-control); font: var(--weight-medium) var(--type-button-size)/1.2 var(--font-sans); text-decoration: none; cursor: pointer; transition: background-color var(--motion-hover), border-color var(--motion-hover), color var(--motion-hover); }
.cf-btn--primary { background: var(--action-primary-bg); color: var(--action-primary-fg); }
.cf-btn--primary:hover { background: var(--action-primary-bg-hover); color: var(--action-primary-fg); }
.cf-btn--secondary { background: transparent; border-color: var(--border-control); color: var(--text-body); }
.cf-btn--secondary:hover { border-color: var(--cf-champagne); color: var(--text-body); }
.cf-btn--text { min-height: 0; padding: 0; background: none; color: var(--cf-champagne); font-size: var(--type-ui-size); }
.cf-btn--text:hover { color: var(--cf-champagne-hover); text-decoration: underline; text-underline-offset: 4px; }
.cf-btn:active { transform: translateY(1px); }
.cf-btn[aria-disabled="true"], .cf-btn:disabled { opacity: 0.45; cursor: not-allowed; transform: none; }
.cf-btn--block { display: flex; width: 100%; }

/* ===== Stage badge & heading ===== */
.cf-badge { display: inline-flex; align-items: center; gap: 7px; align-self: flex-start; padding: 5px 11px; border: 1px solid; border-radius: var(--radius-pill); font: var(--weight-medium) var(--type-badge-size)/1.2 var(--font-sans); white-space: nowrap; }
.cf-badge--sm { gap: 6px; padding: 3px 9px; font-size: 12px; }
.cf-badge--released { color: var(--stage-released); border-color: var(--stage-released-border); }
.cf-badge--soon { color: var(--stage-soon); border-color: var(--stage-soon-border); }
.cf-badge--workshop { color: var(--stage-workshop); border-color: var(--stage-workshop-border); border-style: dashed; }
.cf-stage-heading { display: flex; align-items: center; gap: 14px; padding-bottom: 18px; border-bottom: 1px solid var(--border-subtle); }
.cf-stage-heading h2 { margin: 0; font: var(--weight-medium) var(--type-h2-size)/var(--type-h2-lh) var(--font-sans); letter-spacing: var(--type-h2-track); color: var(--text-body); }
.cf-stage-heading .cf-stage-icon { width: 28px; height: 28px; }
.cf-stage-heading--released { color: var(--stage-released); }
.cf-stage-heading--soon { color: var(--stage-soon); }
.cf-stage-heading--workshop { color: var(--stage-workshop); }
@media (max-width: 720px) { .cf-stage-heading { gap: 10px; padding-bottom: 12px; } .cf-stage-heading .cf-stage-icon { width: 22px; height: 22px; } }

/* ===== Game card ===== */
.cf-card { display: flex; flex-direction: column; background: var(--surface-card); border: 1px solid var(--border-subtle); border-radius: var(--radius-card); overflow: hidden; color: var(--text-body); text-decoration: none; transition: border-color var(--motion-hover); }
a.cf-card:hover { border-color: var(--border-control); color: var(--text-body); }
.cf-card__media { display: block; background: var(--cf-art-backdrop); }
.cf-card__media img { display: block; width: 100%; height: 100%; aspect-ratio: 1200 / 630; object-fit: cover; }
.cf-placeholder { display: flex; align-items: center; justify-content: center; width: 100%; aspect-ratio: 1200 / 630; background: repeating-linear-gradient(135deg, var(--cf-stripe-a) 0 10px, var(--cf-stripe-b) 10px 20px); font: var(--weight-regular) var(--type-mono-size)/1.3 var(--font-mono); letter-spacing: 0.06em; color: var(--text-caption); text-align: center; }
.cf-card__body { display: flex; flex-direction: column; gap: 14px; padding: 28px 32px 32px; flex: 1; }
.cf-card__title { margin: 0; font: var(--weight-medium) var(--type-h3-size)/var(--type-h3-lh) var(--font-sans); letter-spacing: -0.01em; }
.cf-card__line { margin: 0; font: var(--weight-regular) var(--type-body-size)/var(--type-body-lh) var(--font-serif); color: var(--text-secondary); text-wrap: pretty; }
.cf-card__more { margin-top: 6px; font: var(--weight-medium) var(--type-ui-size)/1.2 var(--font-sans); color: var(--cf-champagne); }
.cf-card__actions { display: flex; flex-wrap: wrap; gap: 12px; margin-top: auto; padding-top: 8px; }
.cf-card--feature { display: grid; grid-template-columns: minmax(0, 1.35fr) minmax(0, 1fr); }
.cf-card--feature .cf-card__body { gap: 18px; padding: 36px 40px; }
.cf-card--feature .cf-card__title { font-size: var(--type-h3-feature-size); }
.cf-card--feature .cf-card__line { font-size: 19px; }
.cf-card--workshop { gap: 14px; padding: 28px; background: transparent; border-style: dashed; border-color: var(--border-control); }
.cf-card--workshop .cf-card__title { font-size: var(--type-h3-workshop-size); line-height: 1.2; color: var(--cf-text-workshop-title); }
.cf-card--workshop .cf-card__line { font-size: 17px; color: var(--cf-text-workshop); }
.cf-card__tag { font: italic var(--weight-regular) 16px/1.2 var(--font-serif); color: var(--text-muted); }
.cf-crosslink { grid-column: 1 / -1; display: flex; flex-wrap: wrap; align-items: center; gap: 8px 14px; padding: 16px 24px; border-top: 1px solid var(--border-subtle); font: var(--weight-regular) var(--type-ui-size)/1.4 var(--font-sans); color: var(--text-secondary); text-decoration: none; }
.cf-crosslink:hover { background: var(--surface-card-hover); color: var(--text-body); }
.cf-crosslink__arrow { color: var(--cf-teal); }
.cf-crosslink__title { color: var(--text-body); font-weight: var(--weight-medium); }
@media (max-width: 720px) {
  .cf-card--feature { display: flex; }
  .cf-card__body, .cf-card--feature .cf-card__body { padding: 20px; gap: 12px; }
  .cf-card--feature .cf-card__line { font-size: 17px; }
  .cf-card--workshop { padding: 20px; gap: 12px; }
  .cf-card--workshop .cf-card__line { font-size: 16px; }
  .cf-card__actions { flex-direction: column; gap: 10px; }
  .cf-card__actions .cf-btn { width: 100%; }
  .cf-crosslink { padding: 14px 20px; font-size: 14px; }
}

/* ===== Long-text page ===== */
.cf-longtext { max-width: 680px; margin: 0 auto; padding: 96px var(--gutter) 128px; box-sizing: content-box; }
.cf-longtext__title { margin: 0 0 40px; font: var(--weight-medium) var(--type-h1-size)/var(--type-h1-lh) var(--font-sans); letter-spacing: -0.015em; color: var(--text-display); text-wrap: balance; }
.cf-longtext__meta { margin: -24px 0 40px; font: var(--weight-regular) 14px/1.4 var(--font-sans); color: var(--text-muted); }
.cf-prose { font: var(--weight-regular) var(--type-prose-size)/var(--type-prose-lh) var(--font-serif); color: var(--text-secondary); }
.cf-prose > * { margin: 0 0 1.1em; }
.cf-prose h2 { margin: 2em 0 0.6em; font: var(--weight-medium) 24px/1.25 var(--font-sans); color: var(--text-body); }
.cf-prose h3 { margin: 1.6em 0 0.5em; font: var(--weight-medium) 19px/1.3 var(--font-sans); color: var(--text-body); }
.cf-prose a { color: var(--link-inline); text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 3px; }
.cf-prose a:hover { color: var(--cf-arc-3); }
.cf-prose ul, .cf-prose ol { padding-left: 1.3em; }
.cf-prose li { margin-bottom: 0.4em; }
.cf-prose strong { color: var(--text-body); font-weight: 600; }
.cf-prose code, .cf-modem { font-family: var(--font-mono); font-size: 0.85em; letter-spacing: 0.04em; }
@media (max-width: 720px) { .cf-longtext { padding: 48px var(--gutter) 72px; } .cf-longtext__title { margin-bottom: 28px; } }

/* Site-level styles: what the bundle's frames do with inline styles and its
   React components do with props. Everything here uses tokens; no raw colours (D13). */

/* ===== Tower mark: colours and the inside-out order =====
   The bundle sets stroke colours as SVG attributes and the delays as inline
   styles. Classes do the same job without a style attribute (D11). */
.cf-mark__off { stroke: var(--cf-arc-off); }
.cf-mark__arc--1 { stroke: var(--cf-arc-1); }
.cf-mark__arc--2 { stroke: var(--cf-arc-2); }
.cf-mark__arc--3 { stroke: var(--cf-arc-3); }
.cf-mark__arc--4 { stroke: var(--cf-arc-4); }
.cf-mark__metal { stroke: var(--cf-champagne); }
.cf-mark__dot { stroke: var(--cf-arc-4); }

/* Step 0 is the innermost arc: it lights first, then each next arc one step later. */
.cf-mark--animate .cf-mark__lit.cf-mark__lit--step-0 { animation-delay: var(--motion-arc-first); }
.cf-mark--animate .cf-mark__lit.cf-mark__lit--step-1 { animation-delay: calc(var(--motion-arc-first) + var(--motion-arc-step)); }
.cf-mark--animate .cf-mark__lit.cf-mark__lit--step-2 { animation-delay: calc(var(--motion-arc-first) + 2 * var(--motion-arc-step)); }
.cf-mark--animate .cf-mark__lit.cf-mark__lit--step-3 { animation-delay: calc(var(--motion-arc-first) + 3 * var(--motion-arc-step)); }

/* ===== Hero (Home A Transmission / Home A FR Mobile) ===== */
.cf-hero { display: flex; flex-direction: column; align-items: center; text-align: center; padding: var(--hero-pad-top) var(--space-24) var(--hero-pad-bottom); }
.cf-hero__mark { width: 320px; height: auto; aspect-ratio: 1 / 1; max-width: 70vw; }
.cf-hero__title { margin: var(--space-28) 0 0; font: var(--weight-medium) var(--type-display-size)/var(--type-display-lh) var(--font-sans); letter-spacing: var(--type-display-track); color: var(--text-display); text-wrap: balance; }
.cf-hero__sub { margin: var(--space-24) 0 0; max-width: 560px; font: var(--weight-regular) var(--type-lead-size)/var(--type-lead-lh) var(--font-serif); color: var(--text-secondary); text-wrap: pretty; }
@media (max-width: 720px) {
  .cf-hero { padding-left: var(--space-20); padding-right: var(--space-20); }
  .cf-hero__mark { width: 220px; }
  .cf-hero__title { margin-top: 22px; }
  .cf-hero__sub { margin-top: var(--space-18); }
}

/* ===== Arrows (← → ↗) =====
   Drawn, not set in a font: no shipped face has them. One em square, in the
   text colour, sitting on the baseline like a glyph.
   --arrow-gap is the one gap between an arrow and its text, whichever comes
   first. The markup carries no space next to an arrow (see arrows.ts). */
:root { --arrow-gap: 0.4em; }
.cf-arrow { display: inline-block; flex: none; width: 1em; height: 1em; vertical-align: -0.125em; }
.cf-arrow--after, .cf-arrow--between { margin-inline-start: var(--arrow-gap); }
.cf-arrow--before, .cf-arrow--between { margin-inline-end: var(--arrow-gap); }

/* ===== Catalog: the stage sections of Home and Games =====
   Layout from Home A Transmission / Home A FR Mobile and the UI kit's Home. */
.cf-catalog { display: flex; flex-direction: column; gap: var(--section-gap); max-width: var(--page-max); margin: 0 auto; padding: 0 var(--gutter) var(--hero-pad-bottom); }
.cf-stage { display: flex; flex-direction: column; gap: var(--space-28); }
.cf-stage__games { display: grid; gap: var(--space-28); }
.cf-stage__games--soon { grid-template-columns: repeat(auto-fit, minmax(min(100%, 420px), 1fr)); }
.cf-stage__games--workshop { grid-template-columns: repeat(auto-fit, minmax(min(100%, 300px), 1fr)); gap: var(--space-24); }
.cf-stage__closing { margin: var(--space-8) 0 0; font: italic var(--weight-regular) 20px/1.4 var(--font-serif); color: var(--text-muted); }
.cf-card__media picture { display: block; height: 100%; }
/* A cross-link lands on a Workshop card: leave it some air. The jump is instant:
   nothing scrolls smoothly (the site's only motions are the two tower marks). */
.cf-card--workshop { scroll-margin-top: var(--space-24); }
/* The strip sits inside a card that clips its overflow, so the usual ring (3 px outside) would be cut
   off on three sides. Draw it just inside the strip instead. */
.cf-crosslink:focus-visible { outline-offset: -4px; }
@media (max-width: 720px) {
  .cf-stage, .cf-stage__games, .cf-stage__games--workshop { gap: var(--space-18); }
  .cf-stage__closing { margin-top: var(--space-4); font-size: 18px; }
}

/* ===== Page heading: pages without a hero (Games) =====
   The h1 of the long-text page, on the catalog's column. */
.cf-page-head { max-width: var(--page-max); margin: 0 auto; padding: var(--space-72) var(--gutter) var(--space-56); }
.cf-page-title { margin: 0; font: var(--weight-medium) var(--type-h1-size)/var(--type-h1-lh) var(--font-sans); letter-spacing: -0.015em; color: var(--text-display); text-wrap: balance; }
@media (max-width: 720px) { .cf-page-head { padding-top: var(--space-48); padding-bottom: var(--space-32); } }

/* ===== About =====
   The long-text page, with the master mark fully lit and still above the
   heading (no animation: Home lights up, About is lit, the 404 cannot connect).
   The 404's size: 160 px, 128 px on a phone. */
.cf-about__mark { width: 160px; height: auto; aspect-ratio: 1 / 1; margin: 0 0 var(--space-40); }
@media (max-width: 720px) { .cf-about__mark { width: 128px; margin-bottom: var(--space-28); } }

/* ===== Contact =====
   No frame: the long-text page, with a list of label and address instead of
   prose. The label is UI text (sans), the address reads like the prose's
   inline links. On a phone each row stacks, and the link is a full tap target. */
.cf-contact { display: flex; flex-direction: column; margin: 0; border-top: 1px solid var(--border-subtle); }
.cf-contact__row { display: grid; grid-template-columns: 10em minmax(0, 1fr); align-items: baseline; gap: var(--space-24); padding: var(--space-20) 0; border-bottom: 1px solid var(--border-subtle); }
.cf-contact dt { font: var(--weight-medium) var(--type-ui-size)/1.4 var(--font-sans); color: var(--text-muted); }
.cf-contact dd { margin: 0; font: var(--weight-regular) var(--type-prose-size)/var(--type-prose-lh) var(--font-serif); overflow-wrap: anywhere; }
.cf-contact a { color: var(--link-inline); text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 3px; }
.cf-contact a:hover { color: var(--cf-arc-3); }
@media (max-width: 720px) {
  .cf-contact__row { grid-template-columns: minmax(0, 1fr); gap: 0; padding: var(--space-14) 0 var(--space-6); }
  .cf-contact a { display: inline-flex; align-items: center; min-height: var(--tap-min); }
}

/* ===== Game page (task 03) =====
   No frame: composed from the design system (round 2b was cancelled). The
   Released card's split (art | text) at page width, chosen at STOP A; it stacks
   at 720 px, art on top. The markup keeps the reading order (back, badge, name,
   lead, paragraph, actions, art, support line) and the art is placed with CSS. */
.cf-game__page { display: flex; flex-direction: column; gap: var(--space-40); max-width: var(--page-max); margin: 0 auto; padding: var(--space-72) var(--gutter) var(--hero-pad-bottom); }
.cf-game__back { align-self: flex-start; }
.cf-game__split .cf-card__media { grid-row: 1; grid-column: 1; }
.cf-game__split .cf-card__body { grid-row: 1; grid-column: 2; }
/* Side by side, the art sits at the top of its cell, so it keeps its 1200 × 630
   shape when the text beside it is taller (This Arrow). Stacked, it must not:
   the card is then a flex column, and "start" would shrink the art to its content. */
.cf-game__split .cf-card__media { align-self: start; }
.cf-game__title { margin: 0; font: var(--weight-medium) var(--type-h1-size)/var(--type-h1-lh) var(--font-sans); letter-spacing: -0.015em; color: var(--text-display); text-wrap: balance; }
.cf-game__lead { margin: 0; font: var(--weight-regular) var(--type-lead-size)/var(--type-lead-lh) var(--font-serif); color: var(--text-body); text-wrap: pretty; }
.cf-game__text { margin: 0; font: var(--weight-regular) var(--type-prose-size)/var(--type-prose-lh) var(--font-serif); color: var(--text-secondary); text-wrap: pretty; }
/* Screenshots: the Coming soon cards' grid, so they are drawn at a card's widths,
   each framed like a card's art. They keep their own shape (16:9). */
.cf-game__gallery { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 420px), 1fr)); gap: var(--space-28); }
.cf-game__shot { border: 1px solid var(--border-subtle); border-radius: var(--radius-card); overflow: hidden; background: var(--cf-art-backdrop); }
.cf-game__shot img { display: block; width: 100%; height: auto; }
.cf-game__support { margin: 0; padding-top: var(--space-24); border-top: 1px solid var(--border-subtle); font: var(--weight-regular) var(--type-ui-size)/1.6 var(--font-sans); color: var(--text-muted); overflow-wrap: anywhere; }
.cf-game__support a { color: var(--link-inline); text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 3px; }
.cf-game__support a:hover { color: var(--cf-arc-3); }
@media (max-width: 720px) {
  .cf-game__page { gap: var(--space-28); padding-top: var(--space-48); }
  .cf-game__split .cf-card__media { order: -1; align-self: stretch; }
  .cf-game__gallery { gap: var(--space-18); }
  .cf-game__support a { display: inline-flex; align-items: center; min-height: var(--tap-min); }
}

/* ===== Navigation: the current section =====
   On a game page, Games is the section the visitor is in (aria-current="true"),
   and looks the same as the current page's own entry (components.css). */
.cf-navlink[aria-current="true"] { color: var(--cf-champagne); text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 7px; }

/* ===== Mobile menu without JavaScript =====
   The flag script puts class "js" on <html>. Without it there is no button that
   could fail to work: the links are simply shown, stacked under the header bar. */
@media (max-width: 720px) {
  html:not(.js) .cf-menu-btn { display: none; }
  html:not(.js) .cf-header { flex-wrap: wrap; }
  html:not(.js) .cf-menu { display: flex; flex-direction: column; flex-basis: 100%; }
}

/* ===== 404 =====
   No frame: the hero's centred column, with the mark one step smaller in
   presence (still the four-arc master), the modem's words in mono, the message
   as the page's h1, and the way home. */
.cf-notfound { display: flex; flex-direction: column; align-items: center; text-align: center; padding: var(--hero-pad-top) var(--gutter) var(--hero-pad-bottom); }
.cf-notfound__mark { width: 160px; height: auto; aspect-ratio: 1 / 1; }
.cf-notfound__modem { margin: var(--space-32) 0 0; font-size: var(--type-mono-size); letter-spacing: var(--type-mono-track); color: var(--text-caption); }
.cf-notfound__message { margin: var(--space-16) 0 0; font: var(--weight-medium) var(--type-h1-size)/var(--type-h1-lh) var(--font-sans); letter-spacing: -0.015em; color: var(--text-display); text-wrap: balance; }
.cf-notfound__action { margin: var(--space-40) 0 0; }
@media (max-width: 720px) {
  .cf-notfound__mark { width: 128px; }
  .cf-notfound__modem { margin-top: var(--space-24); }
  .cf-notfound__action { margin-top: var(--space-32); }
}

/* The 404's motion: "trying to connect, and failing". The site's second
   deliberate motion (D10): the hero lights up, the 404 fails to light.
   - The mark rests dark: the lamp and the inner arc are at opacity 0 before,
     after and without the animation. The three outer arcs have no lit layer.
   - One fixed, hand-written sequence over --motion-nocarrier-duration, played
     once: the same on every load. Opacity only, and no JavaScript.
   - Times below are in seconds at the 2.4 s duration (2.5% = 0.06 s).
     Lamp, five attempts: 0.12-0.30 (peak 0.55), 0.48-0.66 (0.75),
     0.96-1.32 (0.90, held: it almost catches), 1.56-1.74 (0.60),
     1.98-2.22 (0.30). Inner arc, two fainter ones, inside the lamp's third and
     fourth: 1.02-1.32 (0.40), 1.56-1.74 (0.15).
   - Flashes (WCAG 2.3.1, at most three in any one second): no one-second
     window holds more than two whole attempts, or touches more than three.
     A test recomputes this from the keyframes. */
.cf-mark--nocarrier .cf-mark__lit, .cf-mark--nocarrier .cf-mark__dot { opacity: 0; animation: var(--motion-nocarrier-duration) linear 1; }
.cf-mark--nocarrier .cf-mark__dot { animation-name: cf-nocarrier-lamp; }
.cf-mark--nocarrier .cf-mark__lit { animation-name: cf-nocarrier-arc; }
@keyframes cf-nocarrier-lamp {
  0%, 5% { opacity: 0; }
  7.5% { opacity: 0.55; }
  12.5%, 20% { opacity: 0; }
  22.5% { opacity: 0.75; }
  27.5%, 40% { opacity: 0; }
  42.5% { opacity: 0.9; }
  50% { opacity: 0.85; }
  55%, 65% { opacity: 0; }
  67.5% { opacity: 0.6; }
  72.5%, 82.5% { opacity: 0; }
  85% { opacity: 0.3; }
  92.5%, 100% { opacity: 0; }
}
@keyframes cf-nocarrier-arc {
  0%, 42.5% { opacity: 0; }
  47.5% { opacity: 0.4; }
  55%, 65% { opacity: 0; }
  67.5% { opacity: 0.15; }
  72.5%, 100% { opacity: 0; }
}
@media (prefers-reduced-motion: reduce) {
  .cf-mark--nocarrier .cf-mark__lit, .cf-mark--nocarrier .cf-mark__dot { animation: none; opacity: 0; }
}

/* ===== Missing copy (D8): visible in a dev build; a production build fails on it ===== */
.cf-copy-needed { padding: 0 var(--space-6); border: 1px dashed var(--cf-teal); border-radius: var(--radius-control); background: none; color: var(--cf-teal); font-family: var(--font-mono); }
