/* ──────────────────────────────────────────────────────────────────
   LEDGER · apothecary register stylesheet
   one file. no framework. external asset: /assets/img/apothecary-hero.webp
   palette: LEDGER-G3.5 candlelit-apothecary (dark)

   POST-PIVOT ROLE (canonical as of GC-5):
   - ledger-cyber.css is the authoritative theme (see assets/css/ledger-cyber.css).
   - This file is the SHARED BASE: fonts, resets, layout primitives.
   - Two categories of rule still rely on this file:
     a) DELIBERATE CHROME LAYER (kept indefinitely): topbar, .brand, .nav, .who,
        .page, .container, .footer, h1, h2, hr.rule, .stack-lg. These render on
        the cyber body class and are intentionally left in apothecary; verified
        legible at GC-4 close.
     b) DUAL-CLASS REMNANTS (prunable in a future GC-final pass): apothecary
        rules whose markup ALSO carries an equivalent ledger-cyber-* class.
        Audit method: for each .foo here, grep PHP markup for
        `class="...foo... ledger-cyber-foo..."`. If ALL references are dual-
        class, the apothecary rule is safe to delete. If even one reference is
        solo-apothecary, keep.

   GC-final (CLOSED 2026-05-27 0055Z) audited: every class in this file is
   referenced by at least one PHP file. No truly-dead classes exist; the dual-
   class audit was not performed in that gate to avoid visual regression.
   Defer the prune to a careful operator-driven sweep when there is appetite.
   ────────────────────────────────────────────────────────────────── */

/* ─── fonts ─────────────────────────────────────────────────────── */

@font-face {
  font-family: "EB Garamond";
  src: url("fonts/EBGaramond-Regular.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "EB Garamond";
  src: url("fonts/EBGaramond-Italic.woff2") format("woff2");
  font-weight: 400;
  font-style: italic;
  font-display: swap;
}
@font-face {
  font-family: "EB Garamond";
  src: url("fonts/EBGaramond-Medium.woff2") format("woff2");
  font-weight: 500;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "JetBrains Mono";
  src: url("fonts/JetBrainsMono-Regular.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "JetBrains Mono";
  src: url("fonts/JetBrainsMono-Medium.woff2") format("woff2");
  font-weight: 500;
  font-style: normal;
  font-display: swap;
}

/* ─── tokens ────────────────────────────────────────────────────── */

:root {
  /* G3.5 palette (candlelit apothecary, dark) */
  --ledger-bg:                #1C1814;
  --ledger-bg-raised:         #241F1A;
  --ledger-bg-edge:           #2A2420;

  --ledger-text:              #C9B896;
  --ledger-text-dim:          #A8987C;
  --ledger-text-faint:        #7A6E58;   /* 3.69:1, AA-exempt roles only */

  --ledger-rule:              #3A3128;
  --ledger-rule-strong:       #5A4D3E;

  --ledger-accent:            #C99A55;
  --ledger-accent-dim:        #8E6B3A;

  --ledger-danger:            #B85048;   /* 3.77:1, oxblood; non-text-UI + AA-large only */

  --ledger-form-field-bg:     #221C17;
  --ledger-form-field-border: #3A3128;
  --ledger-form-field-focus:  #C99A55;

  --ledger-stamp-live:        #D4A574;
  --ledger-stamp-sold-out:    #8A9477;
  --ledger-stamp-dsc:         #8A7E6E;
  --ledger-stamp-hidden:      #3A3128;   /* 1.46:1, intentional, hidden means staged */
  --ledger-stamp-trashed:     #B85048;
  --ledger-stamp-draft:       #7A6E58;

  /* legacy aliases (paper/ink era) remapped to G3.5.
     Kept so existing rules and PHP inline styles render with the new palette
     without a global rewrite. */
  --paper:        var(--ledger-bg);
  --paper-2:      var(--ledger-bg-raised);
  --paper-edge:   var(--ledger-bg-edge);
  --ink:          var(--ledger-text);
  --ink-2:        var(--ledger-text-dim);
  --ink-3:        var(--ledger-text-faint);
  --rule:         var(--ledger-rule);
  --rule-strong:  var(--ledger-rule-strong);
  --vermilion:    var(--ledger-accent);
  --oxblood:      var(--ledger-danger);
  --moss:         var(--ledger-stamp-sold-out);

  /* type */
  --serif: "EB Garamond", "Iowan Old Style", "Hoefler Text", Georgia, serif;
  --mono:  "JetBrains Mono", ui-monospace, "SF Mono", Menlo, Consolas, monospace;

  /* metrics */
  --measure: 68ch;
  --gutter: 24px;
  --hair: 1px;

  color-scheme: dark;
}

/* ─── reset ─────────────────────────────────────────────────────── */

*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
body, h1, h2, h3, h4, h5, p, ul, ol, figure, table, form, fieldset, legend {
  margin: 0; padding: 0;
}
ul, ol { list-style: none; }
button { font: inherit; color: inherit; background: none; border: 0; cursor: pointer; }
a { color: inherit; text-decoration: none; }
img, svg { display: block; max-width: 100%; }

/* ─── base ──────────────────────────────────────────────────────── */

html { background: var(--ledger-bg); }
body {
  font-family: var(--serif);
  font-size: 17px;
  line-height: 1.55;
  color: var(--ledger-text);
  background: var(--ledger-bg);
  font-feature-settings: "tnum" 1, "kern" 1, "liga" 1;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  min-height: 100vh;
  position: relative;
}

/* texture overlay: 4.5% SVG grain, fixed to viewport, pointer-transparent.
   Inline data URI so no extra HTTP request. */
body::before {
  content: "";
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 0;
  opacity: 0.045;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='240' height='240'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' seed='7'/><feColorMatrix values='0 0 0 0 0.78  0 0 0 0 0.72  0 0 0 0 0.58  0 0 0 1 0'/></filter><rect width='100%25' height='100%25' filter='url(%23n)'/></svg>");
  mix-blend-mode: screen;
}
body.notexture::before { display: none; }
body > * { position: relative; z-index: 1; }

/* universal tabular numerals (everywhere a number appears in body copy) */
.num, td.num, .mono, .price, .count, time, .sku, .stamp {
  font-variant-numeric: tabular-nums;
}

/* mono for codes, SKUs, prices, stock counts, timestamps */
.mono, .sku, .price, .count, .stamp, time, code, kbd, samp {
  font-family: var(--mono);
  font-feature-settings: "tnum" 1;
}

/* ─── typography ────────────────────────────────────────────────── */

h1, h2, h3 {
  font-family: var(--serif);
  font-weight: 500;
  line-height: 1.2;
  color: var(--ledger-text);
}
h1 { font-size: 38px; letter-spacing: 0.005em; }
h2 { font-size: 24px; letter-spacing: 0.01em; }
h3 { font-size: 18px; letter-spacing: 0.02em; }

p { max-width: var(--measure); }
em { font-style: italic; color: var(--ledger-text); }
strong { font-weight: 500; }

a:focus-visible, button:focus-visible, input:focus-visible,
select:focus-visible, textarea:focus-visible, summary:focus-visible {
  outline: 2px solid var(--ledger-accent);
  outline-offset: 2px;
}

/* small caps label, used for field labels, column headers, metadata */
.label, .topbar nav a, thead th {
  font-family: var(--serif);
  font-feature-settings: "smcp" 1, "c2sc" 1, "tnum" 1;
  font-variant-caps: all-small-caps;
  letter-spacing: 0.08em;
  color: var(--ledger-text-dim);
  font-weight: 400;
  text-transform: lowercase;
}

/* rendered product name, small caps lowercase, source data stays lowercase */
.name {
  font-family: var(--serif);
  font-feature-settings: "smcp" 1, "c2sc" 1, "tnum" 1;
  font-variant-caps: all-small-caps;
  letter-spacing: 0.06em;
  color: var(--ledger-text);
  font-weight: 500;
  font-size: 1.15em;
}

.muted { color: var(--ledger-text-dim); }
.faint { color: var(--ledger-text-faint); }   /* AA-exempt roles only */
.struck { text-decoration: line-through; color: var(--ledger-text-faint); }

/* ─── layout primitives ────────────────────────────────────────── */

.page    { min-height: 100vh; display: flex; flex-direction: column; }
.container { width: 100%; max-width: 1100px; margin: 0 auto; padding: 28px var(--gutter); }
.stack > * + * { margin-top: 14px; }
.stack-lg > * + * { margin-top: 28px; }

/* hairline rule, the defining visual of this theme */
.rule, hr {
  border: 0;
  border-top: var(--hair) solid var(--ledger-rule);
  margin: 18px 0;
}
.rule-strong { border-top-color: var(--ledger-rule-strong); }

/* a section break with a centered label */
.legend {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  gap: 14px;
  align-items: center;
  color: var(--ledger-text-dim);
  font-feature-settings: "smcp" 1, "c2sc" 1;
  font-variant-caps: all-small-caps;
  letter-spacing: 0.12em;
  margin: 22px 0;
}
.legend::before, .legend::after {
  content: ""; height: 0; border-top: var(--hair) solid var(--ledger-rule);
}

/* ─── topbar / chrome ──────────────────────────────────────────── */

.topbar {
  border-bottom: var(--hair) solid var(--ledger-rule);
  background: var(--ledger-bg);
}
.topbar-inner {
  width: 100%; max-width: 1100px; margin: 0 auto;
  display: flex; align-items: baseline; justify-content: space-between;
  padding: 14px var(--gutter);
  gap: 24px;
}
.topbar .brand {
  font-family: var(--serif);
  font-weight: 500;
  font-size: 22px;
  letter-spacing: 0.18em;
  text-transform: none;
  color: var(--ledger-accent);
  text-shadow: 0 0 18px rgba(201, 154, 85, 0.18);
}
.topbar nav { display: flex; gap: 22px; align-items: baseline; flex-wrap: wrap; }
.topbar nav a {
  font-size: 15px;
  color: var(--ledger-text-dim);
  border-bottom: var(--hair) solid transparent;
  padding-bottom: 2px;
  transition: color 80ms linear, border-color 80ms linear;
}
.topbar nav a:hover { color: var(--ledger-text); border-bottom-color: var(--ledger-text); }
.topbar .who {
  font-family: var(--mono); font-size: 12px; color: var(--ledger-text-faint);
  font-variant-caps: normal; letter-spacing: 0; text-transform: none;
}

/* footer chrome with antler silhouette (LEDGER-G3.5-ANTLER, manual SVG trace
   from apothecary-hero.webp). Single closed path, solid fill, no interior
   detail; right half traced from source, left half mirrored across x=100.
   Wired via mask-image so the SVG defines the shape and CSS owns the color
   (background-color). fill="currentColor" in the SVG is preserved per spec
   even though it has no effect on mask alpha. */
.footer {
  border-top: var(--hair) solid var(--ledger-rule);
  margin-top: auto;
  padding: 24px var(--gutter) 18px;
  color: var(--ledger-text-faint);
  font-size: 12px;
  text-align: center;
  font-family: var(--mono);
  position: relative;
}
.footer::before {
  content: "";
  display: block;
  width: 72px;
  height: 58px;
  margin: 0 auto 12px;
  opacity: 0.55;
  background-color: var(--ledger-accent-dim);
  -webkit-mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 200 160' fill='currentColor'><path d='M100 156L118 152Q122 138 118 122Q116 110 113 110L114 108L135 99L123 104L132 88L160 72L142 80L150 58L180 38L160 48L164 25L160 10L148 30L135 55L122 80L110 105L108 108Q100 92 92 108L90 105L78 80L65 55L52 30L40 10L36 25L40 48L20 38L50 58L58 80L40 72L68 88L77 104L65 99L86 108L87 110Q84 110 82 122Q78 138 82 152Z'/></svg>");
          mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 200 160' fill='currentColor'><path d='M100 156L118 152Q122 138 118 122Q116 110 113 110L114 108L135 99L123 104L132 88L160 72L142 80L150 58L180 38L160 48L164 25L160 10L148 30L135 55L122 80L110 105L108 108Q100 92 92 108L90 105L78 80L65 55L52 30L40 10L36 25L40 48L20 38L50 58L58 80L40 72L68 88L77 104L65 99L86 108L87 110Q84 110 82 122Q78 138 82 152Z'/></svg>");
  -webkit-mask-repeat: no-repeat;
          mask-repeat: no-repeat;
  -webkit-mask-position: center;
          mask-position: center;
  -webkit-mask-size: contain;
          mask-size: contain;
}
body.noantler .footer::before { display: none; }

/* ─── forms ─────────────────────────────────────────────────────── */

.field { display: flex; flex-direction: column; gap: 6px; margin-bottom: 18px; }
.field > .label { font-size: 12px; letter-spacing: 0.14em; }

.field input[type=text],
.field input[type=email],
.field input[type=password],
.field input[type=search],
.field input[type=number],
.field textarea,
.field select {
  font-family: var(--serif);
  font-size: 17px;
  color: var(--ledger-text);
  background: var(--ledger-form-field-bg);
  border: var(--hair) solid var(--ledger-form-field-border);
  padding: 8px 10px;
  border-radius: 0;
  appearance: none;
  transition: border-color 80ms linear, background-color 80ms linear;
}
.field input::placeholder, .field textarea::placeholder { color: var(--ledger-text-faint); }

/* Suppress browser-default :invalid styling on required + pattern inputs.
   Without this, Firefox paints a saturated red box-shadow on empty/required
   fields (and some Safari builds add a red border) which leaks UA red through
   the muted G3.5 palette and breaks the "no Halloween store" constraint.
   Validation feedback is delivered via the .notice notice-error bar at the
   top of the form, not field-level UA chrome. The form's novalidate attribute
   only suppresses submit-time tooltips, not :invalid pseudo-class styling. */
.field input:invalid,
.field textarea:invalid,
.field select:invalid {
  box-shadow: none;
}
.field input:focus, .field textarea:focus, .field select:focus {
  outline: none;
  border-color: var(--ledger-rule);
  border-bottom-color: var(--ledger-form-field-focus);
  border-bottom-width: 2px;
  padding-bottom: 7px;        /* keep total height stable when border grows */
  background: var(--ledger-bg-raised);
}
.field textarea { min-height: 88px; resize: vertical; line-height: 1.5; }

/* monospaced fields where authoring monospace is helpful (sku, codes) */
.field input.mono, input.mono { font-family: var(--mono); font-size: 15px; }

/* ─── buttons ───────────────────────────────────────────────────── */

.btn {
  display: inline-flex; align-items: center; justify-content: center;
  font-family: var(--serif);
  font-size: 15px;
  font-weight: 500;
  letter-spacing: 0.06em;
  color: var(--ledger-text);
  background: var(--ledger-bg);
  border: var(--hair) solid var(--ledger-text);
  padding: 8px 18px;
  cursor: pointer;
  text-transform: none;
  transition: background-color 80ms linear, color 80ms linear;
}
.btn:hover { background: var(--ledger-text); color: var(--ledger-bg); }
.btn:active { background: var(--ledger-text); color: var(--ledger-bg); }
.btn[disabled], .btn[aria-disabled=true] {
  color: var(--ledger-text-faint); border-color: var(--ledger-rule); background: var(--ledger-bg); cursor: not-allowed;
}

.btn-quiet {
  border: 0;
  background: transparent;
  color: var(--ledger-text-dim);
  padding: 6px 0;
  border-bottom: var(--hair) solid var(--ledger-rule);
  border-radius: 0;
}
.btn-quiet:hover { color: var(--ledger-text); border-bottom-color: var(--ledger-text); background: transparent; }

.btn-danger {
  color: var(--ledger-danger);
  border-color: var(--ledger-danger);
}
.btn-danger:hover { background: var(--ledger-danger); color: var(--ledger-bg); }

/* an explicit ink-block button for primary submit on auth surfaces */
.btn-block { width: 100%; }

/* ─── tables (.ledger) ─────────────────────────────────────────── */

.ledger {
  width: 100%;
  border-collapse: collapse;
  font-size: 15px;
}
.ledger thead th {
  text-align: left;
  font-size: 11px;
  letter-spacing: 0.16em;
  padding: 12px 14px;
  border-bottom: var(--hair) solid var(--ledger-text);
  background: var(--ledger-bg);
  position: sticky; top: 0; z-index: 1;
}
.ledger tbody td {
  padding: 14px;
  border-bottom: var(--hair) solid var(--ledger-rule);
  vertical-align: top;
}
.ledger tbody tr:hover td { background: var(--ledger-bg-raised); }
.ledger tbody tr.row-discontinued td { color: var(--ledger-text-faint); text-decoration: line-through; }
.ledger td.r, .ledger th.r { text-align: right; }
.ledger td.c, .ledger th.c { text-align: center; }
.ledger td .price { font-weight: 500; }

/* ─── status pills ─────────────────────────────────────────────── */

.pill {
  display: inline-block;
  font-family: var(--serif);
  font-feature-settings: "smcp" 1, "c2sc" 1;
  font-variant-caps: all-small-caps;
  letter-spacing: 0.12em;
  font-size: 12px;
  color: var(--ledger-text);
  padding: 2px 9px;
  border: var(--hair) solid var(--ledger-text);
  background: transparent;
  line-height: 1.4;
}
.pill-live      { color: var(--ledger-stamp-live);     border-color: var(--ledger-stamp-live);     border-bottom: 2px solid var(--ledger-stamp-live); }
.pill-sold-out  { color: var(--ledger-stamp-sold-out); border-color: var(--ledger-stamp-sold-out); }
.pill-dsc       { color: var(--ledger-stamp-dsc);      border-color: var(--ledger-stamp-dsc);      border-bottom-width: 2px; }
.pill-hidden    { color: var(--ledger-stamp-hidden);   border-color: var(--ledger-stamp-hidden);   border-style: dashed; }
.pill-trashed   { color: var(--ledger-stamp-trashed);  border-color: var(--ledger-stamp-trashed);  border-style: dashed; }
.pill-draft     { color: var(--ledger-stamp-draft);    border-color: var(--ledger-stamp-draft); }

/* the SOLD-OUT stamp that sits where a price would be */
.stamp {
  font-family: var(--serif);
  font-feature-settings: "smcp" 1, "c2sc" 1;
  font-variant-caps: all-small-caps;
  letter-spacing: 0.16em;
  font-size: 13px;
  color: var(--ledger-stamp-sold-out);
  border: var(--hair) solid var(--ledger-stamp-sold-out);
  padding: 1px 8px;
}

/* ─── notices ──────────────────────────────────────────────────── */

.notice {
  font-size: 14px;
  padding: 10px 14px;
  border-left: 3px solid var(--ledger-rule-strong);
  background: var(--ledger-bg-raised);
  color: var(--ledger-text);
}
.notice-error { border-left-color: var(--ledger-danger); color: var(--ledger-text); background: var(--ledger-bg-raised); }
.notice-ok    { border-left-color: var(--ledger-stamp-sold-out); }

/* ─── toast ────────────────────────────────────────────────────── */

#toast-rail {
  position: fixed; left: 50%; bottom: 24px;
  transform: translateX(-50%);
  display: flex; flex-direction: column; gap: 10px;
  z-index: 100; pointer-events: none;
}
.toast {
  pointer-events: auto;
  background: var(--ledger-text);
  color: var(--ledger-bg);
  font-family: var(--serif);
  font-size: 14px;
  padding: 10px 16px;
  border: var(--hair) solid var(--ledger-text);
  letter-spacing: 0.02em;
  transform: translateY(8px); opacity: 0;
  transition: transform 160ms ease-out, opacity 160ms ease-out;
}
.toast.shown { transform: translateY(0); opacity: 1; }
.toast .undo {
  margin-left: 14px;
  text-transform: lowercase;
  font-feature-settings: "smcp" 1, "c2sc" 1;
  font-variant-caps: all-small-caps;
  letter-spacing: 0.14em;
  border-bottom: var(--hair) solid var(--ledger-bg);
  cursor: pointer;
}

/* ─── auth surfaces ────────────────────────────────────────────── */

/* Pre-login surfaces (login, register, register_pending) carry the hero.
   Layer 1 (top, gradient overlay): cover, dims everything to ~34% image visibility.
   Layer 2 (bottom, hero webp): contain, native 1:1 aspect preserved. The webp
   composition (centered skull, symmetric bottle stacks, central lamp glow) was
   authored at 1:1 and breaks apart at wide aspect ratios under cover. With
   contain, the image fills vertically on standard desktops and scales whole
   on narrow viewports; void on the horizontal flanks reads as the room
   extending into shadow given the dark palette.
   .noimg on body removes the hero (debug toggle, original prompt: G3.5). */
.auth-page {
  min-height: 100vh;
  display: flex; align-items: center; justify-content: center;
  padding: 40px 20px;
  background-color: var(--ledger-bg);
  background-image:
    linear-gradient(rgba(28, 24, 20, 0.66), rgba(28, 24, 20, 0.66)),
    url("/assets/img/apothecary-hero.webp");
  background-size: cover, contain;
  background-position: center, center;
  background-repeat: no-repeat, no-repeat;
  background-attachment: fixed, fixed;
}
body.noimg.auth-page {
  background-image: none;
}
.auth-form {
  width: 100%;
  max-width: 360px;
}
.auth-brand {
  text-align: center;
  font-size: 24px;
  letter-spacing: 0.32em;
  font-weight: 500;
  margin-bottom: 4px;
  color: var(--ledger-accent);
  text-shadow: 0 0 18px rgba(201, 154, 85, 0.18);
}
.auth-sub {
  text-align: center;
  font-size: 12px;
  letter-spacing: 0.16em;
  color: var(--ledger-text-dim);
  font-feature-settings: "smcp" 1, "c2sc" 1;
  font-variant-caps: all-small-caps;
  margin-bottom: 28px;
}
.auth-rule {
  border: 0;
  border-top: var(--hair) solid var(--ledger-rule-strong);
  width: 80px;
  margin: 6px auto 20px;
}
.auth-foot {
  margin-top: 18px;
  text-align: center;
  font-size: 13px;
  color: var(--ledger-text-dim);
}
.auth-foot a {
  color: var(--ledger-accent);
  border-bottom: var(--hair) solid var(--ledger-rule);
  padding-bottom: 1px;
}
.auth-foot a:hover { color: var(--ledger-text); border-bottom-color: var(--ledger-accent); }

/* Landing-hero card variant, staged for a future public landing surface.
   Not currently attached to any element. Apply to a wrapper to render the
   hero as an inset card rather than full-bleed body bg. */
.landing-hero {
  display: block;
  width: 100%;
  min-height: 360px;
  background-color: var(--ledger-bg);
  background-image:
    linear-gradient(rgba(28, 24, 20, 0.35), rgba(28, 24, 20, 0.55)),
    url("/assets/img/apothecary-hero.webp");
  background-size: cover, contain;
  background-position: center, center;
  background-repeat: no-repeat, no-repeat;
  border: var(--hair) solid var(--ledger-rule);
}

/* ─── reduced motion ───────────────────────────────────────────── */

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    transition-duration: 0ms !important;
    animation-duration: 0ms !important;
  }
  .toast { transform: none; }
}

/* ─── mobile (admin is desktop-first, public must survive phone) ─ */

@media (max-width: 640px) {
  body { font-size: 16px; }
  .container { padding: 20px 16px; }
  .topbar-inner { flex-wrap: wrap; gap: 12px; padding: 12px 16px; }
  .topbar .brand { font-size: 18px; }
  h1 { font-size: 28px; }
  h2 { font-size: 20px; }

  /* Background-attachment: fixed is laggy/broken on most mobile browsers.
     Fall back to scrolling bg on small viewports so the hero still renders. */
  .auth-page { background-attachment: scroll, scroll; }
}
