/* Pamamonya — the Meridian Plate (Track D). Tokens are the entire system
   (§22.1): four material colors, one accent, derived shades. An eleventh
   color fails review by definition. Three compositions of one object:
   Spread (≥1100), Leaf (641–1099 or square), Folio (≤640). */

:root {
  --ink: #0b0806;
  --ink-warm: #16100a;
  --ink-deep: #050302;
  --paper: #ebe3d0;
  --paper-dim: rgba(235, 227, 208, 0.72);
  --ash: #918a7a; /* oklch(0.60 0.02 75) — 5.82:1 on ink; quietness by size, never contrast debt */
  --rule-shade: rgba(122, 114, 100, 0.55);
  --brass: #c9985a;
  --brass-faint: rgba(201, 152, 90, 0.42);
  --plate-mark: rgba(235, 227, 208, 0.26); /* the impressed edge (§14.6) */
  --ease: cubic-bezier(0.22, 1, 0.36, 1);
  /* paper tooth: one deterministic turbulence tile, seeded № 17148450 —
     the grain is cut in code like everything else (§14.5). Served as a
     hashed asset, not a data URI: img-src 'self' stays strict. */
  --grain: url('/assets/grain.ad37c65c.svg');
}

/* ——— Solar inking (§14.4; anchors fixed at G4a, 18 July 2026) ————
   Six custom properties, set once a minute by the inline script from
   the mean altitude of the London and Harare suns. The defaults ARE
   the day state (masikati): without JavaScript this plate is the
   canonical artifact, unchanged. Every mapping is bounded to the
   imperceptible — weather, never theatre. As of Track D all six
   properties have consumers: --ray-extension and --hatch-density
   drive the engraved emblem's solar overlay. */
:root {
  --ink-depth: 0;
  --paper-exposure: 1;
  --brass-warmth: 0;
  --ray-extension: 1;
  --hatch-density: 1;
  --rule-weight: 1;
  --ink-live: var(--ink);
  --paper-live: var(--paper);
  --brass-live: var(--brass);
  --sheet-live: var(--ink); /* the margin paper outside the plate mark */
  --ash-live: var(--ash);
}
@supports (color: color-mix(in oklab, red 50%, blue)) {
  :root {
    --ink-live: color-mix(in oklab, var(--ink) calc(100% - var(--ink-depth) * 55%), var(--ink-deep));
    --paper-live: color-mix(in oklab, var(--paper) calc(var(--paper-exposure) * 100%), var(--ink-deep));
    --brass-live: color-mix(in oklab, var(--brass) calc(100% - var(--brass-warmth) * 22%), #8a5a24);
    /* the sheet reads a breath lighter than the impression it holds (§14.6) */
    --sheet-live: color-mix(in oklab, var(--ink-live) 97.5%, var(--paper));
  }
}

/* ——— Faces (§14.1): the Text (Cardo — the wordmark's own master) and
       the Registry (IBM Plex Mono — typewriter lineage, true №).
       display: optional + metric-tuned fallback = zero CLS either way. */
@font-face {
  font-family: 'Cardo';
  font-style: normal;
  font-weight: 400;
  font-display: optional;
  src: url('/assets/cardo-regular.cdfd9648.woff2') format('woff2');
}
@font-face {
  font-family: 'Cardo';
  font-style: italic;
  font-weight: 400;
  font-display: optional;
  src: url('/assets/cardo-italic.97b34117.woff2') format('woff2');
}
@font-face {
  font-family: 'Plex Registry';
  font-style: normal;
  font-weight: 400;
  font-display: optional;
  src: url('/assets/plexmono-400.444e9cff.woff2') format('woff2');
}
/* Metric-tuned stand-in so the one-visit fallback render holds the layout. */
@font-face {
  font-family: 'Cardo Fallback';
  src: local('Times New Roman');
  size-adjust: 105.23%;
  ascent-override: 94.1%;
  descent-override: 34.57%;
}

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

html,
body {
  margin: 0;
  padding: 0;
}

html {
  background: var(--sheet-live);
  color: var(--paper-live);
  font-feature-settings: 'kern', 'liga', 'calt', 'dlig', 'onum';
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
  hanging-punctuation: first last;
}

body {
  font-family: 'Cardo', 'Cardo Fallback', 'Times New Roman', serif;
  min-height: 100svh;
  background-color: var(--sheet-live);
  background-image: var(--grain);
}

/* ——— Cross-document leaf turn (§17.5): the frame persists. ————— */
@media (prefers-reduced-motion: no-preference) {
  @view-transition {
    navigation: auto;
  }
}
.plate {
  view-transition-name: plate;
}

/* ——— Stage ————————————————————————————————————— */
/* The height doctrine (§19.2): the plate targets a single viewport, but a
   plate that must choose between staying single-viewport and staying whole,
   scrolls. Never overflow: hidden when content exceeds the viewport; never
   clip the legal line. The frame elongates with the content. */
.stage {
  min-height: 100svh;
  min-height: 100dvh;
  padding: clamp(0.875rem, 1.8vw, 1.75rem);
  padding-top: max(clamp(0.875rem, 1.8vw, 1.75rem), env(safe-area-inset-top));
  padding-bottom: max(clamp(0.875rem, 1.8vw, 1.75rem), env(safe-area-inset-bottom));
  padding-left: max(clamp(0.875rem, 1.8vw, 1.75rem), env(safe-area-inset-left));
  padding-right: max(clamp(0.875rem, 1.8vw, 1.75rem), env(safe-area-inset-right));
  display: flex;
  align-items: stretch;
  justify-content: center;
}

/* ——— The plate mark (§14.6): one impressed edge, softly resolved
       corners, margin paper against the impression. No second rule
       anywhere. ——————————————————————————————————— */
.plate {
  flex: 1;
  max-inline-size: 1680px; /* beyond this the page margin grows, not the plate (§19.2) */
  position: relative;
  border: 1px solid var(--plate-mark);
  border-radius: 3px;
  padding: clamp(1.5rem, 4vw, 3.5rem) clamp(1.25rem, 4vw, 4rem);
  display: flex;
  flex-direction: column;
  background-color: var(--ink-live);
  background-image:
    radial-gradient(ellipse 130% 100% at 50% 32%, rgba(22, 16, 10, 0.5) 0%, transparent 55%, rgba(5, 3, 2, 0.4) 100%),
    var(--grain);
}

/* Visual order: corners first, then the body — DOM order is the
   narration (§24.3); CSS places the certificate. */
.page-header { order: 1; }
.rule-top    { order: 2; }
.body        { order: 3; }
.rule-bottom { order: 4; }
.page-footer { order: 5; }

/* ——— The Registry voice —————————————————————— */
.mono {
  font-family: 'Plex Registry', ui-monospace, Menlo, monospace;
  font-size: 0.72rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--ash-live);
  font-weight: 400;
  line-height: 1;
  font-feature-settings: 'tnum';
}

.page-header,
.page-footer {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 1rem;
}

/* brass at punctuation scale only (§14.9) */
.ip {
  color: var(--brass-live);
}

/* the two live points (§17.3): no hover theatrics, a brass underline */
.page-footer a {
  color: inherit;
  text-decoration: none;
  border-bottom: 1px solid transparent;
  transition: border-color 120ms linear;
  padding: 0.35rem 0; /* ≥24px hit area without visual change (§17.4) */
}
.page-footer a:hover {
  border-bottom-color: var(--brass-live);
}
.page-footer a:active {
  border-bottom-width: 1.5px;
}

/* ——— Divider rules: drawn terminals, a 3-dot course ending (§14.6) — */
.rule {
  position: relative;
  height: 3px;
  margin: clamp(1rem, 2vw, 1.5rem) 0;
  opacity: var(--rule-weight);
}
.rule::before {
  content: '';
  position: absolute;
  left: 17px;
  right: 17px;
  top: 1px;
  height: 1px;
  background: var(--rule-shade);
}
.rule::after {
  content: '';
  position: absolute;
  inset: 0;
  background-image:
    radial-gradient(circle closest-side, var(--rule-shade) 97%, transparent),
    radial-gradient(circle closest-side, var(--rule-shade) 97%, transparent),
    radial-gradient(circle closest-side, var(--rule-shade) 97%, transparent),
    radial-gradient(circle closest-side, var(--rule-shade) 97%, transparent),
    radial-gradient(circle closest-side, var(--rule-shade) 97%, transparent),
    radial-gradient(circle closest-side, var(--rule-shade) 97%, transparent);
  background-position:
    left 0 center, left 5px center, left 10px center,
    right 0 center, right 5px center, right 10px center;
  background-size: 3px 3px;
  background-repeat: no-repeat;
}

/* ——— Body (title / emblem / closing) ——————————— */
.body {
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  gap: clamp(1rem, 2.5vw, 2rem);
  padding: clamp(0.5rem, 2vw, 1.5rem) 0;
}

/* ——— Title block ——————————————————————————— */
.title {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: clamp(1.1rem, 2vw, 1.9rem);
}

/* The Inscription (§14.1): the drawn wordmark, three optical cuts,
   inlined by the build. One cut per composition; kerning is drawn in. */
.wordmark {
  margin: 0;
  line-height: 0;
  color: var(--paper-live);
}
.wm {
  display: none;
  height: auto;
}
.wm-spread {
  display: block;
  width: min(46rem, 56vw);
  aspect-ratio: 10335 / 2081;
}
.wm-leaf {
  aspect-ratio: 10462 / 2081;
}
.wm-folio {
  aspect-ratio: 10597 / 2087;
}

.thesis {
  font-weight: 400;
  font-style: italic;
  font-size: clamp(1rem, 1.5vw, 1.3rem);
  color: var(--paper-dim);
  letter-spacing: 0.005em;
  margin: 0;
  max-width: 40ch;
  line-height: 1.45;
  text-wrap: balance;
}

/* ——— The emblem (§15): engraving + its solar overlay ——————— */
.ornament {
  position: relative;
  padding: clamp(0.75rem, 2vw, 1.5rem) 0;
  min-height: 0;
  flex-shrink: 1;
}

.emblem {
  position: relative;
  width: min(clamp(18rem, 46svh, 30rem), 46vw);
}
.emblem img {
  display: block;
  width: 100%;
  height: auto;
  filter: brightness(var(--paper-exposure));
}

/* the overlay: same viewBox, registered over the plate tier. Second
   state (§15.3): two brass beads ride the meridian ring at the true
   hour angles of Harare and London — set by the solar script; without
   it they hold the appointed noon. The night veil lowers the lamp over
   the paper dial after dark; the halos fade with the rays. */
.emblem > svg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  color: var(--paper-live);
  pointer-events: none;
  filter: brightness(var(--paper-exposure));
}
.bead {
  transform-origin: 300px 300px;
  transform: rotate(0deg);
}
.bead .halo {
  opacity: clamp(0, calc((var(--ray-extension) - 0.83) * 5.9), 1);
  transition: opacity 2s linear;
}
.night-veil {
  opacity: 0;
  opacity: clamp(0, calc((var(--hatch-density) - 1.005) * 22), 1);
  transition: opacity 2s linear;
}
@media (prefers-reduced-motion: no-preference) {
  .bead-h { transition: transform 2100ms cubic-bezier(0.19, 0.82, 0.22, 1); }
  .bead-l { transition: transform 2100ms cubic-bezier(0.19, 0.82, 0.22, 1) 240ms; }
  svg.live .bead-h,
  svg.live .bead-l { transition: transform 3s ease; }
}

/* ——— Closing (Shona) ——————————————————————————— */
.closing {
  display: flex;
  align-items: flex-start;
  justify-content: center;
}

.closing-line {
  font-style: italic;
  font-weight: 400;
  font-size: clamp(1.35rem, 2.4vw, 2rem);
  color: var(--paper-live);
  letter-spacing: -0.005em;
  line-height: 1;
}

.brass-stop {
  color: var(--brass-live);
  font-style: normal;
  font-weight: 400;
}

/* ——— The entrance (§17.2): resolve, never reveal. Everything is in
       final position from first paint at ~72% ink and deepens in order —
       frame and marginalia, then name and thesis, then the emblem, the
       Shona line last. Nothing slides; ink darkens in place. ————— */
@media (prefers-reduced-motion: no-preference) {
  .page-header,
  .page-footer,
  .rule {
    animation: settle 320ms var(--ease) both;
  }
  .plate {
    animation: settle-frame 320ms var(--ease) both;
  }
  .wordmark,
  .thesis {
    animation: settle 380ms var(--ease) 150ms both;
  }
  .ornament {
    animation: settle 420ms var(--ease) 280ms both;
  }
  .closing {
    animation: settle 400ms var(--ease) 700ms both;
  }
  @keyframes settle {
    from {
      opacity: 0.72;
      filter: blur(2px);
    }
    to {
      opacity: 1;
      filter: none;
    }
  }
  @keyframes settle-frame {
    from {
      border-color: rgba(235, 227, 208, 0.18);
    }
    to {
      border-color: var(--plate-mark);
    }
  }
}

/* ——— The colophon leaf (§11.2) ————————————————— */
.colophon-body {
  justify-content: center;
  gap: clamp(1.25rem, 3vh, 2rem);
  text-align: center;
}
.colophon-title {
  margin: 0 0 clamp(0.5rem, 2vh, 1.5rem);
  font-size: 0.72rem;
  color: var(--paper-live);
}
.record {
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: 0.8rem;
}
.record .mono {
  font-size: 0.66rem;
  line-height: 1.6;
}
.record address {
  display: inline;
  font-style: normal;
}
.record a {
  color: inherit;
  text-decoration: none;
  border-bottom: 1px solid transparent;
  transition: border-color 120ms linear;
  padding: 0.3rem 0;
}
.record a:hover {
  border-bottom-color: var(--brass-live);
}
/* the colophon's single rule — the one place brass draws a line (§14.9) */
.colophon-rule {
  width: 4rem;
  height: 1px;
  background: var(--brass-faint);
  margin: clamp(0.25rem, 1.5vh, 1rem) auto;
}
.covenant {
  font-style: italic;
  font-size: clamp(1.05rem, 1.6vw, 1.25rem);
  color: var(--paper-live);
  margin: 0;
  max-width: 44ch;
  line-height: 1.5;
  text-wrap: balance;
}
/* below the covenant: unfilled space — the register awaits entries */
.colophon-body .return-link {
  margin-top: clamp(3rem, 12vh, 7rem);
}
@media (prefers-reduced-motion: no-preference) {
  .colophon-body > * {
    animation: settle 400ms var(--ease) both;
  }
  .colophon-body .covenant {
    animation-delay: 300ms;
  }
}

/* ——— Off the plate (the 404): ink, grain, no frame (§11.4) ————— */
.offplate {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 2.25rem;
  text-align: center;
}
.notfound-line {
  font-style: italic;
  font-size: clamp(1.1rem, 1.8vw, 1.5rem);
  color: var(--paper-dim);
  margin: 0;
}
.return-link {
  font-family: 'Plex Registry', ui-monospace, Menlo, monospace;
  font-size: 0.66rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--ash-live);
  text-decoration: none;
  border-bottom: 1px solid var(--brass-faint);
  padding: 0.3rem 0 0.2em;
}
.return-link:hover {
  color: var(--paper-live);
}

/* ——— Utility: aural-only text ————————————————— */
.sr {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* ——— Composition: Leaf (641–1099px, and square-or-taller viewports
       that would break a Spread — §19.2 foldables) ——————————— */
@media (max-width: 1099px), (min-width: 1100px) and (max-aspect-ratio: 1/1) {
  .wm-spread {
    display: none;
  }
  .wm-leaf {
    display: block;
    width: min(36rem, 62vw);
  }
  .plate {
    padding: clamp(1.25rem, 3vw, 2.5rem) clamp(1rem, 3vw, 2.75rem);
  }
  .emblem {
    width: min(clamp(15rem, 40svh, 25rem), 54vw);
  }
}

/* ——— Height algorithm, rungs 1–2 (§19.2): before the page ever scrolls,
       optional vertical gaps compress toward their minima and the emblem
       reduces within its approved range. Rung 5 — scroll — needs no rule:
       nothing hides overflow, so the frame simply elongates. */
@media (max-height: 960px) {
  .plate {
    padding-top: clamp(1rem, 2.4vh, 2.25rem);
    padding-bottom: clamp(1rem, 2.4vh, 2.25rem);
  }
  .body {
    gap: clamp(0.6rem, 1.5vh, 1.25rem);
    padding: 0.25rem 0;
  }
  .emblem {
    width: min(clamp(17rem, 41svh, 27rem), 46vw);
  }
  .ornament {
    padding: clamp(0.4rem, 1.2vh, 1rem) 0;
  }
  .rule {
    margin: clamp(0.6rem, 1.2vh, 1rem) 0;
  }
}

@media (max-height: 700px) {
  .emblem {
    width: min(clamp(12rem, 32svh, 19rem), 46vw);
  }
  .title {
    gap: 0.6rem;
  }
}

/* ——— Composition: Folio (≤640px) — portrait recomposition; the
       emblem grows to dominate, the corners stack, the registry sits
       at its floor size with tracking eased (§14.2, §19.1). ————— */
@media (max-width: 640px) {
  .stage {
    padding: 0.5rem;
    padding-top: max(0.5rem, env(safe-area-inset-top));
    padding-bottom: max(0.5rem, env(safe-area-inset-bottom));
    padding-left: max(0.5rem, env(safe-area-inset-left));
    padding-right: max(0.5rem, env(safe-area-inset-right));
  }
  .plate {
    padding: 1rem 0.85rem;
  }
  .mono {
    font-size: 0.625rem; /* the floor (§14.2) — never below 10px */
    letter-spacing: 0.09em;
    line-height: 1.45;
  }
  .page-header,
  .page-footer {
    flex-direction: column;
    gap: 0.3rem;
  }
  .page-header > .mono:last-child,
  .page-footer > .mono:last-child {
    align-self: flex-end;
  }
  .wm-spread,
  .wm-leaf {
    display: none;
  }
  .wm-folio {
    display: block;
    width: 80vw;
  }
  .title {
    gap: 0.7rem;
  }
  .rule {
    margin: 0.75rem 0;
  }
  .ornament {
    padding: 0.5rem 0;
  }
  .emblem {
    width: min(82vw, 44svh);
  }
  .body {
    padding: 0.25rem 0;
  }
  .record .mono {
    font-size: 0.625rem;
  }
}

/* ——— Landscape phones: the plate lays out at reduced vertical rhythm and
       the frame extends with the scroll — the object elongates; it never
       crops (§19.2). */
@media (orientation: landscape) and (max-height: 520px) {
  .plate {
    min-height: 100svh;
  }
}

/* ——— Focus ring ——————————————————————————————— */
:focus-visible {
  outline: 1px solid var(--brass);
  outline-offset: 4px;
}

/* ——— Print (§14.11): the fourth composition — one monochrome page,
       the single sanctioned inversion; the emblem prints from vector. */
@media print {
  :root,
  html {
    --ink-depth: 0;
    --paper-exposure: 1;
    --brass-warmth: 0;
    --ray-extension: 1;
    --hatch-density: 1;
    --rule-weight: 1;
    background: #fff;
    color-scheme: light; /* the dark canvas must not print */
  }
  body {
    background: #fff;
    color: #111;
  }
  .mono {
    font-size: 7.5pt;
    letter-spacing: 0.12em;
    white-space: nowrap;
  }
  .plate {
    border-color: #111;
    background: none;
    color: #111;
  }
  .wordmark,
  .closing-line,
  .colophon-title,
  .covenant {
    color: #111;
  }
  .mono,
  .thesis,
  .return-link {
    color: #333;
  }
  .ip,
  .brass-stop {
    color: #111;
  }
  .rule::before {
    background: #555;
  }
  /* second state: the dial is already ink on paper — print it straight;
     inverting would negative the artwork. The frame prints light. */
  .emblem img {
    filter: grayscale(1);
  }
  .emblem > svg {
    color: #111;
    filter: none;
  }
  .stage {
    min-height: auto;
  }
  .stage::after {
    content: 'pamamonya.com · MMXXVI';
    position: fixed;
    bottom: 4mm;
    left: 0;
    right: 0;
    text-align: center;
    font-family: 'Plex Registry', ui-monospace, monospace;
    font-size: 8pt;
    letter-spacing: 0.18em;
    color: #555;
  }
}

/* ——— Contrast, transparency, forced colors (§24.4–24.5) ————— */
@media (prefers-contrast: more) {
  :root {
    --ash-live: var(--paper);
    --paper-exposure: 1;
    --ink-depth: 0;
  }
  body,
  .plate {
    background-image: none;
  }
}
@media (prefers-reduced-transparency: reduce) {
  body,
  .plate {
    background-image: none;
  }
}
@media (forced-colors: active) {
  .plate {
    border-color: CanvasText;
  }
  body,
  .plate {
    background-image: none;
  }
  .rule::before {
    background: CanvasText;
  }
  .rule::after {
    background-image: none;
  }
  .colophon-rule {
    background: CanvasText;
  }
}
