/* ============================================================================
   Polyfetti Counter — the shared surface.
   Used by /counter/ (the quote) and /counter/status.html.

   The palette is the subject's own. 朱 (shu) is the vermilion of a 印鑑, the
   single most recognisable object in Japanese paperwork and the thing that
   goes on the certificate we issue. 藍 (ai) is the other classic pigment and
   marks the commercial counter. The ground is warm paper, never white, and
   the faint grid is 原稿用紙 — the surface Japanese documents are written on.

   Nothing here is loaded from a third party except the two Zen fonts, and
   every colour is a token defined once for light and redefined for dark.
   ========================================================================= */

:root {
  color-scheme: light dark;

  --paper:        #FBF8F3;
  --paper-raised: #FFFFFF;
  --paper-sunk:   #F4EFE7;
  --ink:          #1A1714;
  --ink-soft:     #4A4139;
  --muted:        #7C7166;
  --rule:         #E5DDD1;
  --rule-strong:  #D2C7B7;

  --shu:          #C93C26;
  --shu-bright:   #E04A31;
  --shu-wash:     #FBEDE9;
  --shu-edge:     #F0C9BF;

  --ai:           #274A78;
  --ai-bright:    #33619B;
  --ai-wash:      #EAEFF6;
  --ai-edge:      #C3D2E6;

  --good:         #2F7D5B;
  --good-wash:    #E8F3ED;
  --warn:         #9A6510;
  --warn-wash:    #FBF1DF;

  --accent:        var(--shu);
  --accent-bright: var(--shu-bright);
  --accent-wash:   var(--shu-wash);
  --accent-edge:   var(--shu-edge);

  --grid-line: rgba(26, 23, 20, .045);
  --lift-1: 0 1px 2px rgba(40, 30, 20, .06), 0 4px 12px rgba(40, 30, 20, .05);
  --lift-2: 0 2px 4px rgba(40, 30, 20, .07), 0 12px 32px rgba(40, 30, 20, .09);
  --lift-3: 0 4px 8px rgba(40, 30, 20, .08), 0 24px 60px rgba(40, 30, 20, .14);

  --r-sm: 8px; --r-md: 14px; --r-lg: 22px;

  /* The bottom rung. Three rules in quote.css have asked for --step--2 since
     29 August and it was never defined, so those declarations simply did not
     apply and the text inherited its parent size. A broken var() is not an
     error; it is silence, which is why it survived. */
  --step--2: clamp(.7rem, .68rem + .08vw, .76rem);
  --step--1: clamp(.78rem, .76rem + .1vw, .85rem);
  --step-0:  clamp(.95rem, .92rem + .15vw, 1.05rem);
  --step-1:  clamp(1.12rem, 1.05rem + .35vw, 1.38rem);
  --step-2:  clamp(1.4rem, 1.25rem + .7vw, 1.95rem);
  --step-3:  clamp(1.8rem, 1.5rem + 1.4vw, 2.8rem);

  --sans:  "Zen Kaku Gothic New", "Hiragino Kaku Gothic ProN", "Yu Gothic", system-ui, sans-serif;
  --round: "Zen Maru Gothic", "Zen Kaku Gothic New", "Hiragino Maru Gothic ProN", system-ui, sans-serif;
  --mono:  ui-monospace, "SFMono-Regular", "Cascadia Code", Menlo, monospace;
}

:root[data-desk="commercial"] {
  --accent:        var(--ai);
  --accent-bright: var(--ai-bright);
  --accent-wash:   var(--ai-wash);
  --accent-edge:   var(--ai-edge);
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --paper:        #15120E;
    --paper-raised: #1E1A15;
    --paper-sunk:   #100D0A;
    --ink:          #F3EDE2;
    --ink-soft:     #CFC5B7;
    --muted:        #9A8E80;
    --rule:         #2C2620;
    --rule-strong:  #423A31;
    --shu:          #F0654A;
    --shu-bright:   #FF7A5E;
    --shu-wash:     #2A1712;
    --shu-edge:     #57291E;
    --ai:           #7FA8DE;
    --ai-bright:    #9CBEEB;
    --ai-wash:      #121B29;
    --ai-edge:      #27405F;
    --good:         #5FC08F;
    --good-wash:    #10201A;
    --warn:         #D9A54A;
    --warn-wash:    #241C0D;
    --grid-line: rgba(243, 237, 226, .05);
    --lift-1: 0 1px 2px rgba(0,0,0,.4), 0 4px 12px rgba(0,0,0,.3);
    --lift-2: 0 2px 4px rgba(0,0,0,.45), 0 12px 32px rgba(0,0,0,.4);
    --lift-3: 0 4px 8px rgba(0,0,0,.5), 0 24px 60px rgba(0,0,0,.5);
  }
}

:root[data-theme="dark"] {
  --paper:        #15120E;
  --paper-raised: #1E1A15;
  --paper-sunk:   #100D0A;
  --ink:          #F3EDE2;
  --ink-soft:     #CFC5B7;
  --muted:        #9A8E80;
  --rule:         #2C2620;
  --rule-strong:  #423A31;
  --shu:          #F0654A;
  --shu-bright:   #FF7A5E;
  --shu-wash:     #2A1712;
  --shu-edge:     #57291E;
  --ai:           #7FA8DE;
  --ai-bright:    #9CBEEB;
  --ai-wash:      #121B29;
  --ai-edge:      #27405F;
  --good:         #5FC08F;
  --good-wash:    #10201A;
  --warn:         #D9A54A;
  --warn-wash:    #241C0D;
  --grid-line: rgba(243, 237, 226, .05);
  --lift-1: 0 1px 2px rgba(0,0,0,.4), 0 4px 12px rgba(0,0,0,.3);
  --lift-2: 0 2px 4px rgba(0,0,0,.45), 0 12px 32px rgba(0,0,0,.4);
  --lift-3: 0 4px 8px rgba(0,0,0,.5), 0 24px 60px rgba(0,0,0,.5);
}

* { box-sizing: border-box; }

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--sans);
  font-size: var(--step-0);
  line-height: 1.7;
  -webkit-font-smoothing: antialiased;
  background-image:
    linear-gradient(var(--grid-line) 1px, transparent 1px),
    linear-gradient(90deg, var(--grid-line) 1px, transparent 1px);
  background-size: 28px 28px, 28px 28px;
  transition: background-color .4s ease;
}

h1, h2, h3 { font-family: var(--round); font-weight: 700; line-height: 1.25; text-wrap: balance; margin: 0; }
p { margin: 0; }
a { color: var(--accent); }
button, input, select { font: inherit; color: inherit; }
:focus-visible { outline: 3px solid var(--accent); outline-offset: 3px; border-radius: 4px; }

.wrap { width: min(720px, 100% - 2.2rem); margin-inline: auto; }
.wrap-wide { width: min(1100px, 100% - 2.2rem); margin-inline: auto; }

/* ---------- header ------------------------------------------------------ */

.top {
  position: sticky; top: 0; z-index: 40;
  backdrop-filter: blur(14px) saturate(1.3);
  -webkit-backdrop-filter: blur(14px) saturate(1.3);
  background: color-mix(in srgb, var(--paper) 84%, transparent);
  border-bottom: 1px solid var(--rule);
}
.top-in { display: flex; align-items: center; gap: .8rem; padding: .65rem 0; }
.brand { display: flex; align-items: center; gap: .55rem; font-family: var(--round); font-weight: 900; text-decoration: none; color: inherit; }
.brand-mark {
  width: 32px; height: 32px; border-radius: 10px; display: grid; place-items: center;
  background: var(--accent); color: #fff; font-size: .9rem; font-weight: 900;
  box-shadow: var(--lift-1); transition: background .4s ease, transform .3s;
}
.brand:hover .brand-mark { transform: rotate(-6deg) scale(1.05); }
.brand b { font-size: .95rem; display: block; line-height: 1.1; }
.brand small { display: block; font-family: var(--sans); font-size: .55rem; font-weight: 500; letter-spacing: .16em; color: var(--muted); text-transform: uppercase; }
.spacer { flex: 1; }

.pills { display: flex; gap: .2rem; padding: .22rem; background: var(--paper-sunk); border-radius: 999px; border: 1px solid var(--rule); }
.pills button {
  border: 0; background: transparent; padding: .28rem .65rem; border-radius: 999px;
  font-size: var(--step--1); font-weight: 500; cursor: pointer; color: var(--muted);
  transition: background .2s, color .2s;
}
.pills button[aria-pressed="true"] { background: var(--paper-raised); color: var(--ink); box-shadow: var(--lift-1); }

/* ---------- shared blocks ------------------------------------------------ */

.eyebrow {
  display: inline-flex; align-items: center; gap: .4rem; font-size: var(--step--1);
  font-weight: 700; letter-spacing: .09em; text-transform: uppercase; color: var(--accent);
  background: var(--accent-wash); border: 1px solid var(--accent-edge);
  padding: .28rem .65rem; border-radius: 999px; margin-bottom: .9rem;
}
.eyebrow::before { content: ""; width: 6px; height: 6px; border-radius: 50%; background: var(--accent); }

.lede { font-size: var(--step-1); color: var(--ink-soft); line-height: 1.6; max-width: 40ch; }

.card {
  background: var(--paper-raised); border: 1px solid var(--rule);
  border-radius: var(--r-lg); box-shadow: var(--lift-1);
}

.btn {
  border: 0; cursor: pointer; font-family: var(--round); font-weight: 700;
  background: var(--accent); color: #fff; padding: .8rem 1.35rem; border-radius: 999px;
  box-shadow: var(--lift-2); display: inline-flex; align-items: center; justify-content: center; gap: .5rem;
  transition: transform .25s cubic-bezier(.22,1,.36,1), box-shadow .25s, background .3s;
  text-decoration: none;
}
.btn:hover:not(:disabled) { transform: translateY(-2px); box-shadow: var(--lift-3); background: var(--accent-bright); }
.btn:active { transform: translateY(0); }
.btn:disabled { opacity: .5; cursor: not-allowed; box-shadow: none; }
.btn-ghost { background: transparent; color: var(--ink); border: 1px solid var(--rule-strong); box-shadow: none; }
.btn-ghost:hover:not(:disabled) { background: var(--paper-sunk); box-shadow: var(--lift-1); }

.hidden { display: none !important; }
.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

footer { border-top: 1px solid var(--rule); padding: 2rem 0 3rem; margin-top: 3rem; }
footer p { font-size: var(--step--1); color: var(--muted); max-width: 62ch; margin-bottom: .5rem; }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important; animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
  }
}

/* --- consent ---------------------------------------------------------------
   Inline and unmissable, sitting directly above the button it gates. Not a
   modal: a dialogue that appears over the page gets dismissed rather than read,
   and "they clicked it away" is the easiest thing in the world to argue later.
   The checkbox is deliberately larger than the browser default - this is the
   one control on the page that has to be hit deliberately, not by accident. */
.consent {
  display: flex;
  gap: .7rem;
  align-items: flex-start;
  margin: 1.1rem 0 .4rem;
  padding: .85rem 1rem;
  border: 1px solid var(--line);
  border-radius: .5rem;
  background: var(--sunk, rgba(127, 127, 127, .06));
  cursor: pointer;
  font-size: .95rem;
  line-height: 1.55;
}
.consent:focus-within { border-color: var(--accent); }
.consent input[type="checkbox"] {
  flex: none;
  width: 1.25rem;
  height: 1.25rem;
  margin-top: .15rem;
  accent-color: var(--accent);
  cursor: pointer;
}

/* ---------------------------------------------------------------------------
   `.note` — secondary text beside a control or a heading.

   Thirty-three elements across the counter, the tools and the policy pages have
   carried this class since they were written, and the only rule for it in the
   whole site was in console.css, which none of those pages load. So every one of
   them has been rendering as ordinary body text: the same size and colour as the
   sentence above it, which is the opposite of what a note is for.

   Found 2026-09-08 by a scan comparing the classes a page uses against the ones
   its stylesheets declare. Matched to `.lede` above rather than invented: same
   token, same line-height, one step down.
   -------------------------------------------------------------------------- */
.note {
  font-size: var(--step--1);
  color: var(--ink-soft);
  line-height: 1.6;
  margin: 0 0 .8rem;
}

/* ---------------------------------------------------------------------------
   The file drop sheet, shared.

   Moved out of quote.css on 2026-09-08. quote.css is loaded by the three counter
   pages and by neither free tool, so tools/read.html and tools/scan.html - which
   both build a drop zone and both toggle `.over` on dragenter - had no rule for
   any of it. No border, no hover, no drag feedback, no chosen-file state, on the
   two pages the English search wedge is aimed at.

   Found by a scan comparing the classes each page uses against the ones its own
   stylesheets declare. `.over` was the tell: a class applied by JavaScript and
   declared nowhere is invisible until somebody drags a file, which is exactly
   the kind of thing a test suite never does.
   -------------------------------------------------------------------------- */

/* ---------- the drop sheet ----------------------------------------------- */

.drop {
  border: 2px dashed var(--accent-edge); border-radius: var(--r-md);
  background: var(--accent-wash); padding: 1.8rem 1rem; text-align: center;
  display: flex; flex-direction: column; align-items: center; gap: .35rem;
  cursor: pointer; transition: border-color .25s, background .25s, transform .25s;
}
.drop:hover { transform: translateY(-2px); border-color: var(--accent); }
.drop.over { border-color: var(--accent); border-style: solid; transform: scale(1.01); }
.drop.has-file { border-style: solid; border-color: var(--good); background: var(--good-wash); }
.drop-ico { width: 46px; height: 46px; color: var(--accent); margin-bottom: .3rem; }
.drop.has-file .drop-ico { color: var(--good); }
.drop strong { font-family: var(--round); font-size: var(--step-0); }
.drop span { font-size: var(--step--1); color: var(--muted); }

/* Secondary copy and refusal lists, shared for the same reason as the drop sheet:
   the account page uses both and loads neither quote.css nor order.css, so its
   fine print rendered at body size and its refusals rendered without their list
   indent. Same declarations, moved rather than rewritten. */
.fine { font-size: var(--step--1); color: var(--ink-soft); line-height: 1.6; margin-bottom: .5rem; }
.reasons { margin: .6rem 0 1rem; padding-left: 1.1rem; font-size: .88rem; line-height: 1.65; }
.reasons li { margin-bottom: .35rem; }

/* ---------------------------------------------------------------------------
   Shared layout classes, moved here 2026-09-08.

   Every rule below was already declared - in quote.css, status.css, account.css
   or basket.css - and used by pages that load none of those. Same fault as the
   drop sheet above: the declaration exists and the page never sees it.

   `.pad` and `.acts` are the worst of it, because all five free-tool pages use
   both: their cards had no inner padding and their button rows no layout, on the
   pages the English search wedge is aimed at.

   Moved, not rewritten. The pages that already had these render identically.
   -------------------------------------------------------------------------- */

.pad { padding: 1.3rem; }
.pick { display: flex; gap: .55rem; margin-top: .9rem; }
.pick .btn { flex: 1; padding: .6rem .8rem; font-size: var(--step--1); }
.price-note { font-size: var(--step--1); color: var(--ink-soft); max-width: 34ch; margin-top: .3rem; }
.acts { display: flex; gap: .6rem; margin-top: 1rem; flex-wrap: wrap; }
.acts .btn { flex: 1 1 12rem; }
/* This one was inside quote.css's `@media (max-width: 560px)` and the move hoisted it
   out, which would have stacked the pick row at every width. Put back behind the same
   breakpoint - a rule moved out of its media query is a worse bug than the one being
   fixed, because it looks like a deliberate layout. */
@media (max-width: 560px) {
  .pick { flex-direction: column; }
}
.btn-small { font-size: var(--step--1); padding: 8px 14px; }

/* ---------------------------------------------------------------------------
   The chosen-files list, moved out of basket.css 2026-09-08.

   tools/pdf.html builds the same list when somebody picks files to merge, and
   loads counter.css but not basket.css - so the basket showed a laid-out list
   and the PDF tool showed bare bullet points.
   -------------------------------------------------------------------------- */

ul.picked {
  list-style: none;
  margin: 1.1rem 0 0;
  padding: 0;
  display: grid;
  gap: .5rem;
}
ul.picked li {
  display: grid;
  grid-template-columns: 1fr minmax(0, 14rem) auto;
  gap: .6rem;
  align-items: center;
  background: var(--paper-raised);
  border: 1px solid var(--rule);
  border-radius: var(--r-sm);
  padding: .55rem .7rem;
}
ul.picked .name {
  font-size: var(--step--1);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
ul.picked select {
  font: inherit;
  font-size: var(--step--1);
  padding: .4rem .5rem;
  border: 1px solid var(--rule-strong);
  border-radius: var(--r-sm);
  background: var(--paper);
  color: var(--ink);
  width: 100%;
}
ul.picked select:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }

.btn.tiny {
  padding: .35rem .55rem;
  font-size: var(--step--1);
  line-height: 1;
}
