/* RollandPuff -- dark only (ADR-0004 / D-005).
 * Tokens and contrast ratios from docs/DESIGN_SYSTEM.md; every pair below was
 * computed, not eyeballed. Ratios are against the surface each color is
 * actually used on, not just against the page background -- checking only the
 * background is how a value passes on the canvas and fails on a card.
 */

/* ---- typeface ----------------------------------------------------------
 * Archivo Variable, self-hosted (ADR-0006 / D-007). SELF-HOSTING IS NOT A
 * PREFERENCE HERE: a third-party font domain is a privacy leak, a first-paint
 * dependency on somebody else's uptime, and it would breach the CSP, which is
 * default-src 'self' with no font-src escape hatch.
 *
 * This declaration was missing until 2026-09-20 while --rp-font still named
 * "Archivo", so every visitor silently fell through to system-ui and the site
 * rendered in Segoe UI, Roboto or SF depending on the device. A named font
 * with no @font-face fails completely silently -- nothing errors, the page
 * just quietly isn't the brand. That matters more now the wordmark IS the
 * typeface (ADR-0020).
 *
 * One variable file covers 100-900, so the whole weight range costs 34 KB.
 * Licensed SIL OFL 1.1; the notice ships beside the font in fonts/.
 */
@font-face {
  font-family: "Archivo";
  src: url("../fonts/archivo-latin-var.woff2") format("woff2");
  font-weight: 100 900;      /* variable range, not a single cut */
  font-style: normal;
  font-display: swap;        /* text paints immediately in the fallback */
  /* Latin subset only -- matches the file actually shipped. Without this the
     browser downloads the font even for a page of pure CJK. */
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6,
                 U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F,
                 U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF,
                 U+FFFD;
}

:root {
  color-scheme: dark;   /* MANDATORY. Without it, native form controls,
                           scrollbars and autofill render LIGHT on a dark page,
                           which is the commonest reason a dark site looks
                           unfinished. */

  --rp-bg:          #0B0B0C;
  --rp-surface:     #141417;
  --rp-raised:      #1C1C20;
  --rp-line:        #2B2B31;   /* decorative seams only, 1.40:1 */
  --rp-line-strong: #636369;   /* functional borders, 3.08:1 on surface */

  --rp-text:        #F7F6F4;   /* 18.22:1 on bg */
  --rp-text-2:      #B0AFB5;   /*  9.04:1 on bg */
  --rp-text-muted:  #84838B;   /*  5.25 bg / 4.90 surface / 4.53 raised */

  --rp-ember:       #FF6B2C;   /*  6.92:1 on bg, 6.47:1 on surface */
  --rp-ember-ink:   #1A0A00;   /*  6.80:1 on ember */
  --rp-focus:       #8AB4FF;   /*  9.42:1 on bg */

  --rp-1: 4px;  --rp-2: 8px;  --rp-3: 12px; --rp-4: 16px;
  --rp-5: 24px; --rp-6: 32px; --rp-7: 48px; --rp-8: 64px; --rp-9: 96px;

  --rp-radius-sm: 4px;
  --rp-radius-md: 12px;

  --rp-dur-fast: 120ms;
  --rp-dur-slow: 400ms;
  --rp-ease-out: cubic-bezier(0.2, 0, 0, 1);

  --rp-font: "Archivo", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  --rp-max: 34rem;
}

*, *::before, *::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  background: var(--rp-bg);
  color: var(--rp-text);
  font-family: var(--rp-font);
  font-size: 1rem;              /* 16px floor. Smaller is unreadable outdoors
                                   on a phone, which is the real condition. */
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
}

.wrap {
  max-width: var(--rp-max);
  margin: 0 auto;
  padding: var(--rp-5) var(--rp-4) var(--rp-9);
}

/* ---- header ------------------------------------------------------------ */
.site-header { padding: var(--rp-5) var(--rp-4) 0; }
.site-header .wrap { padding: 0; max-width: var(--rp-max); }

/* The wordmark (ADR-0020 / D-021). It is set type, not an image: the mark is
 * the typeface, so it stays selectable, scales with the user's font size, and
 * costs no extra request.
 *
 * The DOM text is "RollandPuff" -- the canonical spelling ADR-0017 requires
 * and check_naming.py enforces. The capitals are a CSS treatment, so the
 * rendered mark can be uppercase without the source ever holding a
 * non-canonical form. */
.brand {
  display: inline-block;
  color: var(--rp-text);
  text-decoration: none;
  font-weight: 600;
  font-size: 0.9375rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  /* Tracking is added AFTER every letter including the last, which pushes the
     mark visually left of anything aligned under it. Reclaim exactly one
     tracking step. */
  margin-right: -0.18em;
}
.brand:hover { color: var(--rp-ember); }

/* ---- type -------------------------------------------------------------- */
h1 {
  font-size: clamp(1.875rem, 1.3rem + 2.8vw, 2.75rem);
  line-height: 1.1;
  letter-spacing: -0.02em;
  font-weight: 700;
  margin: var(--rp-5) 0 var(--rp-4);
}

h2 {
  font-size: 1.125rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--rp-text-2);
  font-weight: 500;
  margin: var(--rp-8) 0 var(--rp-3);
}

p { margin: 0 0 var(--rp-4); }
.lede { font-size: 1.125rem; color: var(--rp-text-2); }
.muted { color: var(--rp-text-muted); font-size: 0.875rem; }

a { color: var(--rp-ember); }

/* ---- the scan acknowledgment (ADR-0011 / D-012) ----------------------- */
/* One quiet inline line. Never a banner, toast or modal -- any of those is an
   interruption placed before the payoff. */
.scanned {
  color: var(--rp-ember);
  font-size: 0.875rem;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  margin: 0;
}

/* ---- the reveal -------------------------------------------------------- */
.reveal {
  animation: rise var(--rp-dur-slow) var(--rp-ease-out) both;
}
.reveal img {
  display: block;
  width: 100%;
  height: auto;
  border-radius: var(--rp-radius-md);
  margin: var(--rp-5) 0;
}

.design-id {
  font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
  font-size: 0.8125rem;
  color: var(--rp-text-muted);
  letter-spacing: 0.06em;
}

@keyframes rise {
  from { opacity: 0; transform: translateY(14px); }
  to   { opacity: 1; transform: none; }
}

/* ---- options ----------------------------------------------------------- */
.card {
  background: var(--rp-surface);
  border-radius: var(--rp-radius-md);
  padding: var(--rp-5);
  margin: 0 0 var(--rp-3);
}
.card h3 { margin: 0 0 var(--rp-2); font-size: 1rem; }
.card p  { margin: 0; color: var(--rp-text-2); font-size: 0.9375rem; }

/* ---- buttons ----------------------------------------------------------- */
.btn {
  display: inline-block;
  min-height: 44px;             /* thumb target */
  padding: var(--rp-3) var(--rp-5);
  border-radius: var(--rp-radius-sm);
  font: inherit;
  font-weight: 500;
  text-decoration: none;
  transition: transform var(--rp-dur-fast) var(--rp-ease-out);
}
.btn:active { transform: scale(0.98); }

.btn-primary {
  background: var(--rp-ember);
  color: var(--rp-ember-ink);   /* 6.80:1 -- ember needs its own ink token,
                                   because body text on ember would fail */
}
.btn-secondary {
  background: transparent;
  color: var(--rp-text);
  border: 1px solid var(--rp-line-strong);   /* functional border, 3.08:1.
                                   The decorative --rp-line is 1.40:1 and
                                   must never be used where the border IS
                                   the affordance. */
}

.actions { display: flex; flex-wrap: wrap; gap: var(--rp-3); margin: var(--rp-6) 0; }

/* ---- footer ------------------------------------------------------------ */
.site-footer {
  border-top: 1px solid var(--rp-line);
  margin-top: var(--rp-9);
  padding: var(--rp-5) var(--rp-4) var(--rp-8);
  color: var(--rp-text-muted);
  font-size: 0.875rem;
}
.site-footer .wrap { padding: 0; }
.site-footer a { color: var(--rp-text-2); }

/* ---- focus ------------------------------------------------------------- */
:focus-visible {
  outline: none;
  box-shadow: 0 0 0 2px var(--rp-bg), 0 0 0 4px var(--rp-focus);
  border-radius: var(--rp-radius-sm);
}

/* ---- reduced motion ---------------------------------------------------- */
/* Not a courtesy. An accessibility requirement. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}

[hidden] { display: none !important; }
