/* Purpozen home and 404. The company's page: paper, ink, and nothing else; an app's own colors appear only inside its card.
 * Design rules: /DESIGN.md. Decision record: docs/redesign-plan.md §8.
 * One file, in this order: tokens → base → header → the company statement → Apps (large cards, then the catalog) → Studio → Contact
 * → states and breakpoints → the Business details dialog → the 404 page.
 * No build, no library, no external request. The app pages (/nowshot/, /remap/) have their own stylesheets and do not read this file.
 */

/* ── Tokens ───────────────────────────────────────────────────────────────
 * The first two blocks are DESIGN.md's token block, value for value. DESIGN.md stays the rule; this block only spells it out.
 * The third block holds what DESIGN.md describes in words but does not give as values (spacing, type scale), plus the layout
 * tokens this page needed. No color is added.
 */
:root {
  /* ── Company layer: paper, ink, nothing else. (DESIGN.md) ── */
  --color-paper:      oklch(1.000 0 0);         /* #ffffff */
  --color-paper-2:    oklch(0.971 0.003 286);   /* #f5f5f7 parchment */
  --color-ink:        oklch(0.232 0.004 286);   /* #1d1d1f */
  --color-ink-2:      oklch(0.501 0.005 286);   /* #636366 supporting text */
  --color-rule:       oklch(0.907 0 0);         /* #e0e0e0 hairline */
  --color-accent:     oklch(0.232 0.004 286);   /* actions are ink; there is no brand hue */
  --color-accent-ink: oklch(1.000 0 0);
  --color-focus:      oklch(0.232 0.004 286);

  /* ── App cards: an app's own colors appear only inside that app's card. (DESIGN.md) ── */
  --nowshot-paper:  oklch(0.154 0.002 107);     /* #0c0c0b */
  --nowshot-ink:    oklch(0.958 0.010 94);      /* #f3f1ea */
  --nowshot-ink-2:  oklch(0.779 0.010 94);      /* #b9b7b0 */
  --nowshot-accent: oklch(0.876 0.155 137);     /* #a3ee86 lime */
  --remap-paper:    oklch(0.960 0.021 47);      /* #ffeee6 deep enough to hold its edge on white paper */
  --remap-ink:      oklch(0.218 0.004 85);      /* #1b1a18 */
  --remap-ink-2:    oklch(0.460 0.009 61);      /* #5c5753 */
  --remap-accent:   oklch(0.509 0.165 35);      /* #b03512 coral for text */

  --font-display: "Pretendard Variable", Pretendard, -apple-system, BlinkMacSystemFont, system-ui, sans-serif;
  --font-body:    "Pretendard Variable", Pretendard, -apple-system, BlinkMacSystemFont, system-ui, sans-serif;
  --font-mono:    ui-monospace, "SF Mono", Menlo, Consolas, monospace;

  --ease-out: cubic-bezier(0.16, 1, 0.3, 1);
  --dur-fast: 180ms;  --dur-base: 240ms;  --dur-slow: 320ms;

  --radius-card: 18px;  --radius-pill: 9999px;  --radius-input: 11px;

  /* ── Added for this build. DESIGN.md names these in prose. ── */

  /* 4-pt spacing scale, named by role. */
  --space-3xs: 0.125rem;  /*   2px */
  --space-2xs: 0.25rem;   /*   4px */
  --space-xs:  0.5rem;    /*   8px */
  --space-sm:  0.75rem;   /*  12px */
  --space-md:  1rem;      /*  16px */
  --space-lg:  1.5rem;    /*  24px */
  --space-xl:  2.5rem;    /*  40px */
  --space-2xl: 4rem;      /*  64px */
  --space-3xl: 6rem;      /*  96px */
  --space-4xl: 9rem;      /* 144px */

  /* Type: five sizes, no more. Body is 17px / 1.47.
     The three large moments (the statement, the studio statement, the mailbox) share the display size. */
  --text-sm:        0.875rem;                               /* 14px · the identity line, the © line */
  --text-base:      1.0625rem;                              /* 17px · body, header links, an app's kind, fact labels, links */
  --text-lg:        clamp(1.25rem, 0.5vw + 1rem, 1.5rem);   /* 20–23px · section labels, an app's one line, fact values, the wordmark */
  --text-xl:        clamp(1.625rem, 2.5vw, 2.25rem);        /* 26–36px · the company's definition, the Seoul time, an app's name */
  --text-display-s: clamp(2.25rem, 3.89vw, 3.5rem);         /* 36–56px · the headline is 54 characters, so the small display step */
  --text-mailbox:   min(var(--text-display-s), 8vw);        /* the display size, but never wider than a 320px screen */

  --weight-text: 400;
  --weight-display: 600;

  --leading-display: 1.08;
  --leading-title:   1.1;
  --leading-statement: 1.2;
  --leading-lede:    1.3;
  --leading-body:    1.47;
  --leading-small:   1.6;

  --tracking-display: -0.03em;
  --tracking-title:   -0.025em;
  --tracking-lede:    -0.015em;
  --tracking-body:    -0.01em;

  /* Layout: one measure; two equal columns for the shelf and the fact sheet. */
  --wrap:         75rem;                         /* 1200px of content */
  --gutter:       clamp(1.25rem, 5vw, 4rem);     /* 20–64px */
  --col-gap:      1.5rem;
  --header-h:     4rem;
  --mark-size:    2rem;                          /* 32px · the brand mark */
  --hero-top:     clamp(2rem, 2.8vw, 2.5rem);    /* 32–40px */
  --hero-bottom:  clamp(3rem, 3.9vw, 3.5rem);    /* 48–56px · heavier below, so the statement sits into the shelf */
  --section-pad:  clamp(4rem, 6.7vw, 6rem);      /* 64–96px */

  /* The product card. */
  --card-pad:      clamp(1.5rem, 2.5vw, 2.25rem);  /* 24–36px */
  --icon:          4.5rem;                         /* 72px · the app icons are 192px files */
  --card-min:      20rem;                          /* 320px · a large card with no screen: identity at the top, links at the bottom */
  --badge-h:       2.5rem;                         /* 40px · the store badges' own minimum height */
  --label-w:       8.5rem;                         /* the label column of the fact sheet */

  --radius-icon:   22.5%;                        /* the platform's icon shape */
  --radius-mark:   21%;                          /* the brand mark's square, as in assets/mark.svg */
  --radius-focus:  4px;
  --rule:          1px;

  --rise: 12px;                                  /* the one reveal: fade up 12px */

  /* Links: a 1px underline sitting 2px under the baseline; 2px on hover. The mailbox is display size, so one step heavier. */
  --underline:        1px;
  --underline-hover:  2px;
  --underline-offset: 2px;
  --underline-display:        2px;
  --underline-display-hover:  3px;
  --underline-display-offset: 0.08em;

  color-scheme: light;
}

/* ── Base ─────────────────────────────────────────────────────────────── */
*, *::before, *::after { box-sizing: border-box; }
html { overflow-x: clip; -webkit-text-size-adjust: 100%; }
body {
  margin: 0; overflow-x: clip;
  background: var(--color-paper); color: var(--color-ink);
  font-family: var(--font-body); font-size: var(--text-base); font-weight: var(--weight-text);
  line-height: var(--leading-body); letter-spacing: var(--tracking-body);
  -webkit-font-smoothing: antialiased; text-rendering: optimizeLegibility;
}
h1, h2, h3, p, figure, ul, dl, dd { margin: 0; }
ul { padding: 0; list-style: none; }
img { display: block; max-width: 100%; height: auto; }
a { color: inherit; text-decoration: none; }
.keep { white-space: nowrap; }
/* Hidden means hidden, whatever display a rule below gives the element (the dialog hides its form and its reveal button this way). */
[hidden] { display: none !important; }
::selection { background: var(--color-ink); color: var(--color-paper); }

/* The page is the company's paper and ink. A card names its own surface and ink once; everything inside reads these. */
:root {
  --surface: var(--color-paper); --on: var(--color-ink); --on-2: var(--color-ink-2);
  --mark: var(--color-ink); --focus: var(--color-focus);
}
.card-nowshot {
  --surface: var(--nowshot-paper); --on: var(--nowshot-ink); --on-2: var(--nowshot-ink-2);
  --mark: var(--nowshot-accent); --focus: var(--nowshot-ink);
}
.card-remap {
  --surface: var(--remap-paper); --on: var(--remap-ink); --on-2: var(--remap-ink-2);
  --mark: var(--remap-accent); --focus: var(--remap-ink);
}

/* The ring shows at once and is never animated. */
:focus-visible { outline: 2px solid var(--focus); outline-offset: 4px; border-radius: var(--radius-focus); }

.wrap { max-width: calc(var(--wrap) + 2 * var(--gutter)); margin-inline: auto; padding-inline: var(--gutter); }

/* Links in running text: ink, a 1px underline. */
.text-link, .facts a, .identity-button {
  text-decoration: underline; text-decoration-thickness: var(--underline); text-underline-offset: var(--underline-offset);
}

/* Section labels are plain headings at a modest size. They sit above what they name, in the same column. */
.label {
  font-family: var(--font-display); font-size: var(--text-lg); font-weight: var(--weight-display); font-style: normal;
  line-height: var(--leading-title); letter-spacing: var(--tracking-title);
}

/* ── Header: the company's name, and the page's three sections ─────────── */
.site-header .wrap {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between;
  gap: 0 var(--space-lg); min-height: var(--header-h);
}
.brand {
  display: inline-flex; align-items: center; gap: var(--space-xs);
  font-family: var(--font-display); font-size: var(--text-lg); font-weight: var(--weight-display);
  line-height: 1; letter-spacing: var(--tracking-title); white-space: nowrap;
}
.brand svg { width: var(--mark-size); height: var(--mark-size); border-radius: var(--radius-mark); background: var(--color-ink); color: var(--color-paper); }
.site-nav ul { display: flex; align-items: center; gap: var(--space-lg); }
.site-nav a { display: inline-block; padding-block: var(--space-sm); white-space: nowrap; text-underline-offset: var(--underline-offset); }

/* ── The company statement ─────────────────────────────────────────────── */
.hero { padding-block: var(--hero-top) var(--hero-bottom); }
.hero-grid { display: grid; grid-template-columns: minmax(0, 1fr); }
.hero h1 {
  min-width: 0; overflow-wrap: anywhere;
  font-family: var(--font-display); font-size: var(--text-display-s); font-weight: var(--weight-display); font-style: normal;
  line-height: var(--leading-display); letter-spacing: var(--tracking-display);
}
.hero h1 span { display: block; text-wrap: balance; }
/* The definition of the company: ink, one step under the headline, read as the statement's last line. */
.hero .lead {
  margin-top: var(--space-md); min-width: 0; text-wrap: balance;
  font-family: var(--font-display); font-size: var(--text-xl);
  line-height: var(--leading-statement); letter-spacing: var(--tracking-title);
}
/* The stamp: where the company is and what time it is there. Tabular numerals, so nothing shifts as it ticks. */
.stamp {
  margin-top: var(--space-lg); white-space: nowrap;
  font-family: var(--font-display); font-size: var(--text-xl); font-variant-numeric: tabular-nums;
  line-height: var(--leading-display); letter-spacing: var(--tracking-title);
}
.stamp span { font-weight: var(--weight-display); }

/* The one entrance on the page, in the order the page is meant to be read: the company, then what it makes. */
.reveal { animation: rise var(--dur-slow) var(--ease-out) both; animation-delay: calc(var(--i, 0) * 80ms); }
@keyframes rise { from { opacity: 0; transform: translateY(var(--rise)); } }

/* ── Apps: one equal card per app ──────────────────────────────────────── */
.apps { padding-bottom: var(--section-pad); }
.shelf { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--col-gap); margin-top: var(--space-lg); }

/* One container signal: the app's own surface and the card radius. No border, no shadow, no screen.
   Who the app is at the top; where to go at the bottom; the card's height is the air between them. */
.card {
  display: grid; grid-template-columns: minmax(0, 1fr); min-height: var(--card-min);
  padding: var(--card-pad); overflow: hidden; overflow: clip;
  border-radius: var(--radius-card); background: var(--surface); color: var(--on);
}
.card-body { display: flex; flex-direction: column; min-width: 0; }
/* Icon, name, kind: set the way a store lists an app, so the card reads as a product. The kind sits under the name. */
.card-id { display: flex; align-items: center; gap: var(--space-md); }
.app-icon { flex: none; width: var(--icon); height: var(--icon); border-radius: var(--radius-icon); }
.card-name { min-width: 0; }
.card h3 {
  min-width: 0; overflow-wrap: anywhere;
  font-family: var(--font-display); font-size: var(--text-xl); font-weight: var(--weight-display); font-style: normal;
  line-height: var(--leading-title); letter-spacing: var(--tracking-title);
}
.kind { color: var(--on-2); }
.line {
  margin-top: var(--space-lg); text-wrap: balance;
  font-size: var(--text-lg); line-height: var(--leading-lede); letter-spacing: var(--tracking-lede);
}
/* The app's own color touches one word per card: the thing the app is about. */
.line em { font-style: normal; color: var(--mark); }

/* The link, then the badges under it. From 72rem a card is wide enough for both cards to hold them on one row. */
.card-actions { display: flex; flex-direction: column; align-items: flex-start; gap: var(--space-2xs) var(--space-lg); margin-top: auto; padding-top: var(--space-xl); }
.text-link { display: inline-block; padding-block: var(--space-sm); white-space: nowrap; }
/* Official badges keep their artwork, colors and proportions. Google's file carries transparent padding
   around the art (41px of 250), so it is drawn taller and pulled in until its art is as tall as Apple's. */
.stores { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-sm); }
.stores a { display: block; line-height: 0; border-radius: var(--radius-focus); transition: opacity var(--dur-fast) var(--ease-out), transform var(--dur-fast) var(--ease-out); }
.stores img { width: auto; max-width: none; height: var(--badge-h); }
.stores img.google-en { height: calc(var(--badge-h) * 1.488); margin: calc(var(--badge-h) * -0.244); }


/* ── Studio: a statement, then facts on hairlines ──────────────────────── */
.studio { padding-block: var(--section-pad); background: var(--color-paper-2); }
.statement {
  margin-top: var(--space-lg); min-width: 0; overflow-wrap: anywhere;
  font-family: var(--font-display); font-size: var(--text-display-s); font-weight: var(--weight-display);
  line-height: var(--leading-display); letter-spacing: var(--tracking-display);
}
.statement span { display: block; text-wrap: balance; }
.facts { display: grid; grid-template-columns: minmax(0, 1fr); column-gap: var(--col-gap); margin-top: var(--space-2xl); }
/* On a phone a row is the label above its value; from 40rem, label and value share the line. */
.facts > div {
  display: grid; grid-template-columns: minmax(0, 1fr); column-gap: var(--space-md); row-gap: var(--space-3xs); align-items: baseline;
  padding-block: var(--space-md); border-top: var(--rule) solid var(--color-rule);
}
.facts > div:last-child { border-bottom: var(--rule) solid var(--color-rule); }
.facts dt { color: var(--color-ink-2); }
.facts dd { font-size: var(--text-lg); line-height: var(--leading-lede); letter-spacing: var(--tracking-lede); }

/* ── Contact: the mailbox is the closing line ──────────────────────────── */
.contact { padding-block: var(--section-pad) var(--space-2xl); }
.mail-line { margin-top: var(--space-lg); }
.mail {
  display: inline-block; white-space: nowrap;
  font-family: var(--font-display); font-size: var(--text-mailbox); font-weight: var(--weight-display);
  line-height: var(--leading-display); letter-spacing: var(--tracking-display);
  text-decoration: underline; text-decoration-thickness: var(--underline-display); text-underline-offset: var(--underline-display-offset);
}
.identity {
  display: flex; flex-wrap: wrap; justify-content: space-between; gap: var(--space-2xs) var(--space-lg);
  margin-top: var(--space-2xl); padding-top: var(--space-lg); border-top: var(--rule) solid var(--color-rule);
  font-size: var(--text-sm); line-height: var(--leading-small); color: var(--color-ink-2);
}
.identity p { text-wrap: balance; }
.identity-button {
  padding: 0; border: 0; background: none; cursor: pointer; white-space: nowrap;
  font: inherit; letter-spacing: inherit; color: var(--color-ink);
}
.identity-button:disabled { opacity: 0.55; cursor: not-allowed; }
/* The button opens a dialog that only script can open (assets/identity.js). Without script it and its separator are not shown,
   and the line reads "Purpozen". */
html:not(.js) .identity-more { display: none; }

/* ── States. One signal each: links gain or thicken an underline, badges dim, everything pressable gives by 3%. ── */
@media (hover: hover) and (pointer: fine) {
  .site-nav a:hover { text-decoration: underline; text-decoration-thickness: var(--underline); }
  .text-link:hover, .facts a:hover, .identity-button:hover:not(:disabled) { text-decoration-thickness: var(--underline-hover); }
  .mail:hover { text-decoration-thickness: var(--underline-display-hover); }
  .stores a:hover { opacity: 0.82; }
}
/* On a touch screen these two get a taller target. The padding is taken back as margin, so the line they sit on keeps its
   height: the fact rows stay equal and the two lines of the identity row stay level. */
@media (pointer: coarse) {
  .identity-button, .facts a { display: inline-block; padding-block: var(--space-sm); margin-block: calc(-1 * var(--space-sm)); }
}
.site-nav a, .text-link, .facts a, .mail, .identity-button { transition: transform var(--dur-fast) var(--ease-out); }
.site-nav a:active, .stores a:active, .text-link:active, .facts a:active, .mail:active, .identity-button:active:not(:disabled) { transform: scale(0.97); }
.facts a { display: inline-block; }

@media (min-width: 40rem) {
  .facts > div { grid-template-columns: var(--label-w) minmax(0, 1fr); }
}

/* ── From 48rem: the apps stand side by side; the time moves up beside the headline's first line ── */
@media (min-width: 48rem) {
  .shelf { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .hero-grid { grid-template-columns: minmax(0, 1fr) auto; column-gap: var(--col-gap); }
  .hero h1 { grid-column: 1 / -1; grid-row: 1; align-self: baseline; }
  .stamp { grid-column: 2; grid-row: 1; justify-self: end; align-self: baseline; margin-top: 0; }
  .hero .lead { grid-column: 1 / -1; grid-row: 2; }
}

/* ── From 48rem: the two facts stand side by side, each a label over its value under one hairline ── */
@media (min-width: 48rem) {
  .facts { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .facts > div, .facts > div:last-child { grid-template-columns: minmax(0, 1fr); row-gap: var(--space-2xs); border-bottom: 0; }
}

/* ── From 72rem: a card's link and badges share one row ────────────────── */
@media (min-width: 72rem) {
  .card-actions { flex-direction: row; align-items: center; }
}

/* ── Reduced motion: no travel, a short crossfade at most. The clock does not start (see the script in index.html). ── */
@media (prefers-reduced-motion: reduce) {
  .reveal { animation: fade 150ms linear both; animation-delay: 0ms; }
  .site-nav a, .stores a, .text-link, .facts a, .mail, .identity-button { transition-duration: 0ms; }
  .site-nav a:active, .stores a:active, .text-link:active, .facts a:active, .mail:active, .identity-button:active:not(:disabled) { transform: none; }
}
@keyframes fade { from { opacity: 0; } }

/* ── The catalog: every app after the two newest. The same anatomy as a large card, compact, on the company's own parchment,
      so the page grows by rows and the two newest stay the only colored things.
      NOT ON THE PAGE YET: two apps are out and both are large cards. These rules are kept for the third app onward
      (DESIGN.md "Notes"; README "앱 추가"). The markup goes inside .apps .wrap, right after .shelf:
        <div class="catalog">
          <article class="app" aria-labelledby="ID">
            <div class="app-id">
              <img class="app-icon" src="/images/APP-icon.png" width="192" height="192" alt="">
              <div class="card-name"><h3 id="ID"><a href="/APP/">Name</a></h3><p class="kind">Kind of app</p></div>
            </div>
            <p class="app-line">One line that says what the app does</p>
            <p class="app-stores"><a href="https://apps.apple.com/us/app/idNNN">App Store</a> · <a href="https://play.google.com/store/apps/details?id=PACKAGE">Google Play</a></p>
          </article>
        </div> ── */
.catalog { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--col-gap); margin-top: var(--col-gap); }
.app {
  position: relative; display: grid; grid-template-columns: minmax(0, 1fr); align-content: start; gap: var(--space-md);
  padding: var(--space-lg); border-radius: var(--radius-card); background: var(--color-paper-2);
}
.app-id { display: flex; align-items: center; gap: var(--space-md); }
.app .app-icon { width: 3.5rem; height: 3.5rem; }
.app h3 {
  font-family: var(--font-display); font-size: var(--text-lg); font-weight: var(--weight-display); font-style: normal;
  line-height: var(--leading-title); letter-spacing: var(--tracking-title);
}
/* The whole card opens the app's page; the store links stay their own targets above it. */
.app h3 a::after { content: ""; position: absolute; inset: 0; border-radius: var(--radius-card); }
.app-line { text-wrap: balance; }
.app-stores { position: relative; z-index: 1; font-size: var(--text-sm); line-height: var(--leading-small); color: var(--color-ink-2); }
.app-stores a { color: var(--color-ink); text-decoration: underline; text-decoration-thickness: var(--underline); text-underline-offset: var(--underline-offset); }
@media (hover: hover) and (pointer: fine) {
  .app:hover h3 a { text-decoration: underline; text-decoration-thickness: var(--underline); text-underline-offset: var(--underline-offset); }
  .app-stores a:hover { text-decoration-thickness: var(--underline-hover); }
}
@media (pointer: coarse) { .app-stores a { display: inline-block; padding-block: var(--space-sm); } }
@media (min-width: 48rem) { .catalog { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (min-width: 64rem) { .catalog { grid-template-columns: repeat(3, minmax(0, 1fr)); } }

/* ── The primary action (DESIGN.md "CTA voice"): ink fill, paper text, pill, 11px × 22px, gives by 3% when pressed.
      Used by the dialog's Confirm and the 404 page's way back. The home itself has none: its actions are the store badges. ── */
.button {
  display: inline-block; padding: 0.6875rem 1.375rem; border: 0; border-radius: var(--radius-pill);
  background: var(--color-accent); color: var(--color-accent-ink); cursor: pointer; white-space: nowrap;
  font: inherit; letter-spacing: inherit;
  transition: opacity var(--dur-fast) var(--ease-out), transform var(--dur-fast) var(--ease-out);
}
.button:active { transform: scale(0.97); }
@media (hover: hover) and (pointer: fine) { .button:hover { opacity: 0.82; } }

/* ── Business details dialog (assets/identity.js). The company and its report numbers show at once; the address and the phone
      number only after the challenge. Paper, ink and hairlines like the fact sheet; the card radius; no shadow (the backdrop
      separates it). The colors of the challenge image itself are drawn by identity.js. ── */
.identity-dialog {
  width: min(35rem, calc(100vw - 2 * var(--space-md))); max-height: calc(100vh - 2 * var(--space-md)); max-height: calc(100dvh - 2 * var(--space-md));
  padding: 0; border: 0; border-radius: var(--radius-card); background: var(--color-paper); color: var(--color-ink);
}
/* A literal color: ::backdrop does not read custom properties in every browser. This is the ink (#1d1d1f) at 45%. */
.identity-dialog::backdrop { background: rgb(29 29 31 / 0.45); }
.identity-dialog > div { position: relative; padding: var(--card-pad); }
.identity-dialog h2 {
  padding-right: var(--space-2xl);
  font-family: var(--font-display); font-size: var(--text-lg); font-weight: var(--weight-display);
  line-height: var(--leading-title); letter-spacing: var(--tracking-title);
}
.identity-close {
  position: absolute; top: calc(var(--card-pad) - 0.625rem); right: calc(var(--card-pad) - 0.625rem);
  width: 2.75rem; height: 2.75rem; padding: 0; border: 0; border-radius: 50%;
  background: var(--color-paper-2); color: var(--color-ink); cursor: pointer;
  font: inherit; font-size: 1.375rem; line-height: 1;
}
.identity-dialog dl { margin-top: var(--space-lg); }
/* On a phone a row is the label above its value; from 40rem, label and value share the line. */
.identity-dialog dl > div {
  display: grid; grid-template-columns: minmax(0, 1fr); column-gap: var(--space-md); row-gap: var(--space-3xs); align-items: baseline;
  padding-block: var(--space-sm); border-top: var(--rule) solid var(--color-rule);
}
.identity-dialog dl > div:last-child { border-bottom: var(--rule) solid var(--color-rule); }
.identity-dialog dt { font-size: var(--text-sm); line-height: var(--leading-small); color: var(--color-ink-2); }
.identity-dialog dd { min-width: 0; overflow-wrap: anywhere; text-wrap: balance; }
.identity-dialog dd[data-secret]:not(.shown) { color: var(--color-ink-2); }
/* The quiet actions are links in ink, as everywhere on the page. */
.identity-dialog dd a, .identity-reveal, .identity-cancel, .identity-refresh {
  text-decoration: underline; text-decoration-thickness: var(--underline); text-underline-offset: var(--underline-offset);
}
.identity-reveal, .identity-cancel, .identity-refresh {
  padding: 0; border: 0; background: none; cursor: pointer; white-space: nowrap;
  font: inherit; letter-spacing: inherit; color: var(--color-ink);
  transition: transform var(--dur-fast) var(--ease-out);
}
.identity-reveal { margin-top: var(--space-lg); }
.identity-form { margin-top: var(--space-md); padding: var(--space-lg); border-radius: var(--radius-input); background: var(--color-paper-2); }
.identity-why, .identity-help { font-size: var(--text-sm); line-height: var(--leading-small); color: var(--color-ink-2); }
.challenge { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-xs) var(--space-md); margin-top: var(--space-md); }
.challenge canvas { display: block; width: 100%; max-width: 18.75rem; height: auto; border-radius: var(--radius-input); }
.identity-form label { display: block; margin-top: var(--space-md); font-size: var(--text-sm); line-height: var(--leading-small); color: var(--color-ink-2); }
/* The field's edge is the supporting ink, not the hairline: a field has to be findable. */
.identity-form input {
  display: block; width: 100%; margin-top: var(--space-2xs); padding: 0.625rem 0.75rem;
  border: var(--rule) solid var(--color-ink-2); border-radius: var(--radius-input); background: var(--color-paper); color: var(--color-ink);
  font: inherit; font-size: var(--text-lg); line-height: var(--leading-lede); letter-spacing: 0.2em; text-transform: uppercase;
}
/* A wrong answer: the field's edge turns to full ink and doubles, and the message says why. There is no error hue. */
.identity-form input[aria-invalid="true"] { padding: calc(0.625rem - 1px) calc(0.75rem - 1px); border-width: 2px; border-color: var(--color-ink); }
.identity-error { min-height: 1.6em; margin-top: var(--space-xs); font-size: var(--text-sm); line-height: var(--leading-small); }
.identity-actions { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-xs) var(--space-lg); margin-top: var(--space-xs); }
.identity-help { margin-top: var(--space-md); }
@media (hover: hover) and (pointer: fine) {
  .identity-dialog dd a:hover, .identity-reveal:hover, .identity-cancel:hover, .identity-refresh:hover { text-decoration-thickness: var(--underline-hover); }
  .identity-close:hover { background: var(--color-rule); }
}
@media (pointer: coarse) {
  .identity-reveal, .identity-cancel, .identity-refresh, .identity-dialog dd a { display: inline-block; padding-block: var(--space-sm); }
  /* The mailbox keeps its row as tall as the others: the larger touch target reaches into the row's own padding. */
  .identity-dialog dd a { margin-block: calc(-1 * var(--space-sm)); }
}
.identity-reveal:active, .identity-cancel:active, .identity-refresh:active, .identity-close:active { transform: scale(0.97); }
@media (min-width: 40rem) {
  .identity-dialog dl > div { grid-template-columns: 14.5rem minmax(0, 1fr); }
}

/* ── 404: the home's header and statement type, and one way back ───────── */
.missing { padding-bottom: var(--section-pad); }
.missing .code { margin-bottom: var(--space-xs); color: var(--color-ink-2); font-variant-numeric: tabular-nums; }
.missing .lead {
  max-width: 30em;
  font-family: var(--font-body); font-size: var(--text-lg); line-height: var(--leading-lede); letter-spacing: var(--tracking-lede);
  color: var(--color-ink-2);
}
.missing .actions { margin-top: var(--space-xl); }

@media (prefers-reduced-motion: reduce) {
  .button, .identity-reveal, .identity-cancel, .identity-refresh { transition-duration: 0ms; }
  .button:active, .identity-reveal:active, .identity-cancel:active, .identity-refresh:active, .identity-close:active { transform: none; }
}
