/* eG Codes — design system.
   One stylesheet for the marketing site, the studio and the admin console, so a
   color or radius change lands everywhere at once. */

:root {
  --ink:        #0B1210;
  --ink-2:      #14201C;
  --forest:     #1B4332;
  --forest-2:   #0D2818;
  --emerald:    #10B981;
  --emerald-d:  #059669;
  --gold:       #C49A2A;
  --paper:      #FFFFFF;
  --cream:      #F6F8F7;
  --line:       #E3E9E6;
  --line-dark:  rgba(255,255,255,.12);
  --text:       #16211D;
  --muted:      #6B7772;
  --muted-dark: #9DB0A8;
  --danger:     #DC2626;
  --warn:       #D97706;
  --ok:         #059669;

  --r-sm: 8px;
  --r:    12px;
  --r-lg: 18px;
  --r-xl: 26px;

  --shadow-sm: 0 1px 2px rgba(11,18,16,.06), 0 1px 3px rgba(11,18,16,.05);
  --shadow:    0 4px 12px rgba(11,18,16,.07), 0 1px 3px rgba(11,18,16,.05);
  --shadow-lg: 0 24px 60px rgba(11,18,16,.16), 0 4px 12px rgba(11,18,16,.06);

  --sans: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
  --mono: ui-monospace, SFMono-Regular, 'SF Mono', Menlo, Consolas, monospace;

  --wrap: 1180px;
}

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

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

body {
  margin: 0;
  font-family: var(--sans);
  color: var(--text);
  background: var(--paper);
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3, h4 { margin: 0 0 .5em; line-height: 1.15; letter-spacing: -.022em; font-weight: 700; }
h1 { font-size: clamp(2.1rem, 5vw, 3.6rem); }
h2 { font-size: clamp(1.6rem, 3.4vw, 2.5rem); }
h3 { font-size: 1.2rem; }
p  { margin: 0 0 1em; }
a  { color: var(--forest); text-decoration: none; }
a:hover { text-decoration: underline; }
img, svg { max-width: 100%; }

.wrap { width: 100%; max-width: var(--wrap); margin: 0 auto; padding: 0 20px; }
.center { text-align: center; }
.muted { color: var(--muted); }
.small { font-size: .875rem; }
.tiny  { font-size: .78rem; }
.mono  { font-family: var(--mono); }
.nowrap { white-space: nowrap; }
.hidden { display: none !important; }
.stack > * + * { margin-top: 12px; }
.row { display: flex; gap: 12px; align-items: center; }
.row.wrapx { flex-wrap: wrap; }
.spread { display: flex; gap: 12px; align-items: center; justify-content: space-between; }
.grow { flex: 1 1 auto; min-width: 0; }

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

.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  font: inherit; font-weight: 600; font-size: .95rem;
  padding: 11px 20px; border-radius: 999px; border: 1px solid transparent;
  cursor: pointer; text-decoration: none; white-space: nowrap;
  transition: transform .12s ease, box-shadow .12s ease, background .12s ease, opacity .12s ease;
}
.btn:hover { text-decoration: none; }
.btn:active { transform: translateY(1px); }
.btn:disabled, .btn[aria-disabled="true"] { opacity: .5; cursor: not-allowed; transform: none; }
.btn-primary { background: var(--forest); color: #fff; box-shadow: var(--shadow-sm); }
.btn-primary:hover { background: var(--forest-2); box-shadow: var(--shadow); }
.btn-accent { background: var(--emerald); color: #04241A; }
.btn-accent:hover { background: var(--emerald-d); color: #fff; }
.btn-ghost { background: transparent; color: var(--text); border-color: var(--line); }
.btn-ghost:hover { background: var(--cream); }
.btn-dark { background: rgba(255,255,255,.1); color: #fff; border-color: var(--line-dark); }
.btn-dark:hover { background: rgba(255,255,255,.18); }
.btn-danger { background: #fff; color: var(--danger); border-color: #F3C4C4; }
.btn-danger:hover { background: #FEF2F2; }
.btn-sm { padding: 7px 14px; font-size: .85rem; }
.btn-lg { padding: 14px 28px; font-size: 1.02rem; }
.btn-block { width: 100%; }

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

label { display: block; font-weight: 600; font-size: .85rem; margin-bottom: 5px; color: var(--text); }
.hint { font-size: .78rem; color: var(--muted); margin-top: 5px; }

input[type=text], input[type=email], input[type=password], input[type=url],
input[type=number], input[type=search], select, textarea {
  width: 100%; font: inherit; font-size: .95rem; color: var(--text);
  padding: 10px 12px; border: 1px solid var(--line); border-radius: var(--r-sm);
  background: #fff; transition: border-color .12s ease, box-shadow .12s ease;
}
input:focus, select:focus, textarea:focus {
  outline: none; border-color: var(--forest);
  box-shadow: 0 0 0 3px rgba(27,67,50,.12);
}
textarea { resize: vertical; min-height: 84px; }
input[type=color] {
  width: 44px; height: 36px; padding: 2px; border: 1px solid var(--line);
  border-radius: var(--r-sm); background: #fff; cursor: pointer;
}
input[type=range] { width: 100%; accent-color: var(--forest); }
.field + .field { margin-top: 14px; }
.check { display: flex; gap: 9px; align-items: flex-start; font-weight: 500; font-size: .9rem; }
.check input { margin-top: 3px; flex: none; }

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

.card {
  background: #fff; border: 1px solid var(--line);
  border-radius: var(--r-lg); padding: 22px; box-shadow: var(--shadow-sm);
}
.card-flush { padding: 0; overflow: hidden; }
.panel { background: var(--cream); border-radius: var(--r-lg); padding: 20px; }

.pill {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 3px 10px; border-radius: 999px;
  font-size: .74rem; font-weight: 700; letter-spacing: .03em; text-transform: uppercase;
  /* var(--muted) clears 4.5:1 on white but only reaches 4.32:1 on the cream
     pill background — and at .74rem uppercase this is small text, so it needs
     the full ratio. Same darkened gray the toggle uses. */
  background: var(--cream); color: #5A6661; border: 1px solid var(--line);
}
.pill-ok    { background: #ECFDF5; color: #047857; border-color: #A7F3D0; }
.pill-warn  { background: #FFFBEB; color: #B45309; border-color: #FDE68A; }
.pill-bad   { background: #FEF2F2; color: #B91C1C; border-color: #FECACA; }
.pill-info  { background: #EFF6FF; color: #1D4ED8; border-color: #BFDBFE; }
.pill-dark  { background: rgba(255,255,255,.1); color: #D7E5DE; border-color: var(--line-dark); }

/* ── tables ────────────────────────────────────────────────────────────── */

table.data { width: 100%; border-collapse: collapse; font-size: .9rem; }
table.data th {
  text-align: left; font-size: .74rem; text-transform: uppercase; letter-spacing: .05em;
  color: var(--muted); font-weight: 700; padding: 10px 12px; border-bottom: 1px solid var(--line);
  white-space: nowrap;
}
table.data td { padding: 12px; border-bottom: 1px solid var(--line); vertical-align: middle; }
table.data tr:last-child td { border-bottom: 0; }
table.data tbody tr:hover { background: var(--cream); }
.table-scroll { overflow-x: auto; -webkit-overflow-scrolling: touch; }

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

.notice { padding: 12px 14px; border-radius: var(--r); font-size: .9rem; border: 1px solid; }
.notice-ok   { background: #ECFDF5; border-color: #A7F3D0; color: #065F46; }
.notice-warn { background: #FFFBEB; border-color: #FDE68A; color: #92400E; }
.notice-bad  { background: #FEF2F2; border-color: #FECACA; color: #991B1B; }
.notice-info { background: #F0F7FF; border-color: #BFDBFE; color: #1E40AF; }

/* ── app chrome ────────────────────────────────────────────────────────── */

.topbar {
  position: sticky; top: 0; z-index: 40;
  background: rgba(255,255,255,.92); backdrop-filter: blur(10px);
  border-bottom: 1px solid var(--line);
}
.topbar .wrap { display: flex; align-items: center; gap: 18px; height: 62px; }
.brand { display: inline-flex; align-items: center; gap: 10px; white-space: nowrap; flex: none; font-weight: 800; letter-spacing: -.02em; color: var(--ink); font-size: 1.06rem; }
.brand:hover { text-decoration: none; }
/* Eddie's block + "eG Codes" as one image; width follows the height (the lockup is ~3.16:1) */
.brand-lockup { display: block; height: 36px; width: auto; flex: none; }
.navlinks { display: flex; gap: 4px; align-items: center; }
.navlinks a {
  color: var(--muted); font-weight: 600; font-size: .9rem;
  padding: 7px 12px; border-radius: var(--r-sm);
}
.navlinks a:hover { background: var(--cream); color: var(--text); text-decoration: none; }
.navlinks a.on { color: var(--forest); background: #EDF5F1; }

.dark-topbar { background: rgba(11,18,16,.86); border-bottom-color: var(--line-dark); }
.dark-topbar .brand { color: #fff; }
.dark-topbar .navlinks a { color: var(--muted-dark); }
.dark-topbar .navlinks a:hover { background: rgba(255,255,255,.08); color: #fff; }

.page { padding: 30px 0 72px; }
.page-head { margin-bottom: 22px; }
.page-head h1 { font-size: 1.85rem; margin-bottom: 4px; }

/* ── marketing ─────────────────────────────────────────────────────────── */

.dark { background: var(--ink); color: #E8F0EC; }
.dark h1, .dark h2, .dark h3 { color: #fff; }
.dark .muted { color: var(--muted-dark); }

/* `:not(.btn)` is load-bearing, not tidiness.
   `.dark a` is (0,1,1) and beats `.btn-accent` at (0,1,0), so without the
   exclusion this rule repaints every anchor-styled button inside a dark section
   emerald — including .btn-accent, whose background is ALSO emerald. That put
   the three main CTAs at a 1.0 contrast ratio: invisible until hover. Buttons
   carry their own color; only real links get the accent treatment. */
.dark a:not(.btn) { color: var(--emerald); }
/* ...and not the header either. The rule above is (0,2,1) and was beating `.dark-topbar .brand`
   and the nav colors at (0,2,0), which painted the logo text and both nav links emerald. */
.dark .dark-topbar a.brand { color: #fff; }
.dark .dark-topbar .navlinks a { color: var(--muted-dark); }
.dark .dark-topbar .navlinks a:hover { color: #fff; }

/* Ghost buttons are near-black text by default, which disappears on a dark
   section. They appear there via the shared topbar (Sign in / Sign out), so the
   dark variant has to exist even though no dark page opts into it explicitly. */
.dark .btn-ghost,
.dark-topbar .btn-ghost {
  color: #E8F0EC;
  border-color: var(--line-dark);
  background: transparent;
}
.dark .btn-ghost:hover,
.dark-topbar .btn-ghost:hover { background: rgba(255, 255, 255, .12); color: #fff; }

.hero { padding: 66px 0 78px; }
.hero-grid { display: grid; grid-template-columns: 1.08fr .92fr; gap: 54px; align-items: center; }
.eyebrow {
  display: inline-flex; align-items: center; gap: 8px;
  font-size: .78rem; font-weight: 700; letter-spacing: .09em; text-transform: uppercase;
  color: var(--emerald); margin-bottom: 16px;
}
.lede { font-size: 1.14rem; color: var(--muted-dark); max-width: 46ch; }
.dark .lede { color: #B9CCC4; }

.section { padding: 74px 0; }
.section-head { max-width: 62ch; margin: 0 auto 44px; text-align: center; }

.grid-3 { display: grid; grid-template-columns: repeat(3, 1fr); gap: 20px; }
.grid-2 { display: grid; grid-template-columns: repeat(2, 1fr); gap: 20px; }
.grid-4 { display: grid; grid-template-columns: repeat(4, 1fr); gap: 18px; }

.feature { padding: 24px; border-radius: var(--r-lg); background: #fff; border: 1px solid var(--line); }
.feature h3 { font-size: 1.05rem; margin-bottom: 6px; }
.feature p { margin: 0; color: var(--muted); font-size: .93rem; }
.feature-icon {
  width: 40px; height: 40px; border-radius: 11px; margin-bottom: 14px;
  display: grid; place-items: center; background: #EDF5F1; color: var(--forest);
}

/* pricing */
/* auto-fit, not a fixed count: the number of plans is admin data, and a column count set from
   JS (as this used to be) beats every media query — which is how four plans ended up side by
   side on a phone and pushed the whole page 440px wider than the screen. */
.price-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); gap: 18px; align-items: stretch; }
.plan { min-width: 0; }
.plan {
  display: flex; flex-direction: column; background: #fff;
  border: 1px solid var(--line); border-radius: var(--r-xl); padding: 26px 22px;
}
.plan.featured { border-color: var(--forest); box-shadow: var(--shadow-lg); position: relative; }
.plan.featured::before {
  content: attr(data-badge); position: absolute; top: -11px; left: 50%; transform: translateX(-50%);
  background: var(--forest); color: #fff; font-size: .68rem; font-weight: 800;
  letter-spacing: .08em; text-transform: uppercase; padding: 4px 12px; border-radius: 999px;
}
.plan-name { font-size: .82rem; font-weight: 800; letter-spacing: .07em; text-transform: uppercase; color: var(--muted); }
.plan-price { font-size: 2.5rem; font-weight: 800; letter-spacing: -.03em; margin: 10px 0 2px; }
.plan-price small { font-size: .95rem; font-weight: 600; color: var(--muted); letter-spacing: 0; }
.plan-feats { list-style: none; padding: 0; margin: 18px 0 22px; flex: 1 1 auto; }
.plan-feats li { display: flex; gap: 9px; align-items: flex-start; font-size: .9rem; padding: 5px 0; }
.plan-feats li::before { content: '✓'; color: var(--emerald-d); font-weight: 800; flex: none; }
.plan-feats li.off { color: var(--muted); }
.plan-feats li.off::before { content: '—'; color: var(--line); }

.toggle-wrap { display: inline-flex; background: var(--cream); border-radius: 999px; padding: 4px; gap: 4px; border: 1px solid var(--line); }
.toggle-wrap button {
  font: inherit; font-weight: 600; font-size: .86rem; border: 0; background: transparent;
  padding: 7px 16px; border-radius: 999px; cursor: pointer;
  /* Not var(--muted): on the cream track that lands at 4.37:1, just under the
     4.5 floor. This is a control, not caption text — it has to be readable in
     its unselected state or nobody finds the yearly prices. */
  color: #5A6661;
}
.toggle-wrap button.on { background: #fff; color: var(--text); box-shadow: var(--shadow-sm); }

/* ── studio ────────────────────────────────────────────────────────────── */

.studio-grid { display: grid; grid-template-columns: 380px 1fr; gap: 26px; align-items: start; }
.studio-preview { position: sticky; top: 84px; }
.preview-stage {
  display: grid; place-items: center; padding: 26px; border-radius: var(--r-xl);
  /* The chosen preview surface (--pv-bg, set by the studio) under a faint checker,
     so a transparent background still reads as transparent on any colour. */
  background:
    repeating-conic-gradient(rgba(128,128,128,.13) 0 25%, transparent 0 50%) 0 0/20px 20px,
    var(--pv-bg, #fff);
  border: 1px solid var(--line); min-height: 300px;
}
.preview-stage svg { width: min(360px, 100%); height: auto; display: block; }
.preview-stage.is-dark .muted { color: var(--muted-dark); }
/* No destination yet: the current design on a sample code, faded, with the prompt over it. */
.stage-sample { position: relative; display: grid; place-items: center; width: min(360px, 100%); }
.stage-sample svg { opacity: .22; filter: saturate(.7); }
.stage-sample-msg {
  position: absolute; margin: 0; padding: 7px 14px; border-radius: 999px;
  background: rgba(255,255,255,.92); color: var(--text); font-size: .86rem; font-weight: 600;
  box-shadow: 0 2px 10px rgba(0,0,0,.08); text-align: center;
}
.preview-note { margin: 0; padding: 7px 12px; border-radius: var(--r-sm); background: var(--cream); color: var(--text); }
.backdrop-row { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 10px; margin-top: -4px; }
.backdrop-row .chip { padding: 4px 11px; font-size: .78rem; }
.backdrop-row input[type=color] { width: 34px; height: 28px; padding: 0; border: 1px solid var(--line); border-radius: 8px; }

.opt-group { border-top: 1px solid var(--line); padding: 16px 0; }
.opt-group:first-child { border-top: 0; padding-top: 0; }
.opt-group > summary {
  font-weight: 700; font-size: .92rem; cursor: pointer; list-style: none;
  display: flex; justify-content: space-between; align-items: center; padding: 2px 0;
}
.opt-group > summary::-webkit-details-marker { display: none; }
.opt-group > summary::after { content: '⌄'; color: var(--muted); font-size: 1.1rem; line-height: 1; }
.opt-group[open] > summary::after { content: '⌃'; }
.opt-body { padding-top: 14px; }

.swatches { display: flex; flex-wrap: wrap; gap: 8px; }
.swatch {
  width: 42px; height: 42px; border-radius: 11px; border: 2px solid transparent;
  cursor: pointer; padding: 0; box-shadow: inset 0 0 0 1px rgba(0,0,0,.08);
}
.swatch.on { border-color: var(--ink); }

/* Studio style presets: a live sample code per preset, its name underneath. */
.presets { display: grid; grid-template-columns: repeat(4, 1fr); gap: 12px 10px; }
@media (max-width: 620px) { .presets { grid-template-columns: repeat(3, 1fr); } }
.preset {
  font: inherit; background: none; border: 0; padding: 0; cursor: pointer;
  display: flex; flex-direction: column; align-items: center; gap: 6px; min-width: 0;
}
.preset-thumb {
  width: 64px; height: 64px; display: grid; place-items: center; overflow: hidden;
  border-radius: 12px; background: #fff; padding: 4px;
  box-shadow: inset 0 0 0 1px var(--line); transition: box-shadow .12s;
}
.preset-thumb svg { width: 100%; height: 100%; display: block; }
.preset-name { font-size: .78rem; font-weight: 600; color: var(--muted); line-height: 1.1; }
.preset:hover .preset-thumb { box-shadow: inset 0 0 0 1px var(--forest); }
.preset:focus-visible { outline: none; }
.preset:focus-visible .preset-thumb { box-shadow: 0 0 0 2px #fff, 0 0 0 4px var(--muted); }
.preset.on .preset-thumb { box-shadow: 0 0 0 2px #fff, 0 0 0 4px var(--forest); }
.preset.on .preset-name { color: var(--forest); font-weight: 800; }
.preset-current {
  margin-left: auto; margin-right: 10px; font-size: .78rem; font-weight: 700;
  color: var(--forest); background: #EDF5F1; padding: 2px 9px; border-radius: 999px;
}
.preset-current:empty { display: none; }
.preset-current.is-custom { color: var(--muted); background: var(--cream); }

.chipset { display: flex; flex-wrap: wrap; gap: 7px; }
.chip {
  font: inherit; font-size: .82rem; font-weight: 600; padding: 6px 13px;
  border-radius: 999px; border: 1px solid var(--line); background: #fff;
  color: var(--muted); cursor: pointer;
}
.chip:hover { border-color: var(--forest); color: var(--text); }
.chip.on { background: var(--forest); border-color: var(--forest); color: #fff; }
.chip .chip-n { opacity: .7; font-weight: 500; margin-left: 2px; }
.linkrow { cursor: pointer; }
.linkrow:hover strong, .linkrow:focus-visible strong { color: var(--forest); }

.verify-line { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 10px; }
.verify-tag {
  font-size: .72rem; font-weight: 700; padding: 3px 8px; border-radius: 6px;
  background: #ECFDF5; color: #047857;
}
.verify-tag.no { background: #FEF2F2; color: #B91C1C; }

/* ── code list ─────────────────────────────────────────────────────────── */

/* 320 not 268: a code card carries a name, a destination, a short link and five
   actions. At 268 the auto-fill packed four columns into the page and left the
   text column too narrow to show any of it. */
.code-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(320px, 1fr)); gap: 18px; }
.code-card { display: flex; flex-direction: column; gap: 14px; }
.code-thumb {
  width: 96px; height: 96px; flex: none; border-radius: var(--r); background: var(--cream);
  display: grid; place-items: center; overflow: hidden; border: 1px solid var(--line);
}
.code-thumb svg, .code-thumb img { width: 100%; height: 100%; }

/* The name must win the row against the type pill. Without `min-width:0` a flex
   item refuses to shrink below its content, so the fixed-width pill took the
   space and the name collapsed to a single letter plus an ellipsis. */
.code-name {
  flex: 1 1 auto; min-width: 0;
  /* Two lines, then ellipsis. A single nowrap line left barely 100px next to the
     thumbnail and the type pill on a phone, which turned "Chamber directory rack
     card" into "C…" — the name is how you tell your codes apart, so it gets to
     wrap before it gets to truncate. */
  display: -webkit-box; -webkit-line-clamp: 2; line-clamp: 2;
  -webkit-box-orient: vertical; overflow: hidden; overflow-wrap: anywhere;
}
.code-card .pill { flex: none; }

/* A short link is one long unbroken token. Normal wrapping cannot break it, so
   it ran straight out of the card. `anywhere` lets it break mid-string — and it
   must stay fully readable, never ellipsised, because people copy it by eye off
   this card and onto artwork. */
.code-short {
  margin: 4px 0 0; font-size: .76rem;
  overflow-wrap: anywhere; word-break: break-word; line-height: 1.4;
}
/* The destination, by contrast, IS safe to truncate — it is a full URL with a
   title tooltip, and the authoritative copy is one click away in the editor. */
.code-target {
  margin: 6px 0 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

.meter { height: 7px; border-radius: 999px; background: var(--line); overflow: hidden; }
.meter > span { display: block; height: 100%; background: var(--forest); border-radius: 999px; }
.meter.warn > span { background: var(--warn); }
.meter.full > span { background: var(--danger); }

.stat { padding: 16px 18px; border-radius: var(--r-lg); background: #fff; border: 1px solid var(--line); }
.stat-num { font-size: 1.7rem; font-weight: 800; letter-spacing: -.03em; line-height: 1.1; }
.stat-label { font-size: .78rem; text-transform: uppercase; letter-spacing: .05em; color: var(--muted); font-weight: 700; }

.spark { display: flex; align-items: flex-end; gap: 2px; height: 46px; }
.spark i { flex: 1 1 0; background: #CFE2D8; border-radius: 2px 2px 0 0; min-height: 2px; }
.spark i.hot { background: var(--forest); }

/* ── modal ─────────────────────────────────────────────────────────────── */

.modal-back {
  position: fixed; inset: 0; z-index: 90; background: rgba(11,18,16,.55);
  display: grid; place-items: center; padding: 20px; backdrop-filter: blur(3px);
}
.modal {
  background: #fff; border-radius: var(--r-xl); width: min(560px, 100%);
  max-height: 88vh; overflow: auto; box-shadow: var(--shadow-lg); padding: 26px;
}
.modal h2 { font-size: 1.35rem; }

/* ── misc ──────────────────────────────────────────────────────────────── */

.skeleton {
  background: linear-gradient(90deg, #EEF2F0 25%, #F7FAF9 37%, #EEF2F0 63%);
  background-size: 400% 100%; animation: sk 1.3s ease infinite; border-radius: var(--r-sm);
}
@keyframes sk { 0% { background-position: 100% 50%; } 100% { background-position: 0 50%; } }

.empty { text-align: center; padding: 56px 20px; color: var(--muted); }
.empty h3 { color: var(--text); }

.footer { padding: 40px 0; border-top: 1px solid var(--line-dark); font-size: .88rem; }

.copy-field {
  display: flex; align-items: center; gap: 8px; background: var(--cream);
  border: 1px solid var(--line); border-radius: var(--r-sm); padding: 8px 8px 8px 12px;
}
.copy-field code { flex: 1 1 auto; font-size: .84rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.tabs { display: flex; gap: 4px; border-bottom: 1px solid var(--line); margin-bottom: 22px; flex-wrap: wrap; }
.tabs button {
  font: inherit; font-weight: 600; font-size: .92rem; border: 0; background: transparent;
  padding: 11px 15px; cursor: pointer; color: var(--muted);
  border-bottom: 2px solid transparent; margin-bottom: -1px;
}
.tabs button.on { color: var(--forest); border-bottom-color: var(--forest); }

@media (max-width: 900px) {
  .hero-grid, .studio-grid, .grid-2 { grid-template-columns: 1fr; }
  .grid-3, .grid-4 { grid-template-columns: repeat(2, 1fr); }
  .studio-preview { position: static; }
  .hero { padding: 44px 0 52px; }
  .section { padding: 52px 0; }
}
@media (max-width: 620px) {
  .grid-3, .grid-4 { grid-template-columns: 1fr; }
  /* Give the text column back ~24px on a phone. The thumbnail is a recognition
     aid, not the content. */
  .code-thumb { width: 72px; height: 72px; }
}

/* ── phone header ──────────────────────────────────────────────────────────
   One 62px row cannot hold a logo, a nav and two buttons at 375px: the brand
   wrapped onto two lines and "How it works" stacked into three. So the bar
   becomes two rows — brand and account on top, the nav underneath as a strip
   that scrolls sideways if it ever has to. Nothing wraps, nothing overlaps. */
@media (max-width: 720px) {
  .topbar .wrap { flex-wrap: wrap; height: auto; gap: 0 12px; padding-top: 10px; padding-bottom: 0; }
  .topbar .brand { height: 40px; }
  .topbar #authSlot { margin-left: auto; gap: 8px; min-width: 0; }
  /* the signed-in email is the first thing to go: it is on the Account page */
  .topbar #authSlot > span { display: none; }
  .topbar .navlinks {
    order: 3; flex: 1 0 100%; gap: 2px; margin: 6px -8px 0; padding: 0 0 8px;
    overflow-x: auto; scrollbar-width: none; -webkit-overflow-scrolling: touch;
  }
  .topbar .navlinks::-webkit-scrollbar { display: none; }
  .topbar .navlinks a { flex: none; white-space: nowrap; padding: 7px 10px; font-size: .88rem; }
  .topbar .navlinks:empty { display: none; }
  .topbar .wrap:has(.navlinks:empty) { padding-bottom: 10px; }
  .toggle-wrap button { padding: 7px 12px; }
  .page-head.spread { flex-wrap: wrap; align-items: flex-start; }
  .page-head.spread > * { min-width: 0; }
  #saveRow { flex: 1 0 100%; min-width: 0; }
  #saveRow .btn { flex: 1 1 0; min-width: 0; padding-left: 12px; padding-right: 12px; }
}
@media (max-width: 360px) {
  .topbar #authSlot .btn { padding: 7px 11px; font-size: .82rem; }
}


/* ── Support view ("view as customer") ─────────────────────────────────────
   A superadmin looking at somebody else's account. Loud on purpose: the
   failure mode of every impersonation feature is forgetting you are in one.

   Sticky at the very top, ABOVE the topbar (z 50 vs 40), and the topbar is
   pushed down by exactly the bar's measured height (--viewas-h, set in JS)
   so the two stack instead of overlapping at any wrap width. */
.viewas-bar {
  position: sticky; top: 0; z-index: 50;
  background: var(--ink); color: #fff;
  border-bottom: 2px solid var(--warn);
}
.viewas-inner {
  display: flex; align-items: center; gap: 12px;
  flex-wrap: wrap;
  padding: 9px 20px;
  font-size: .86rem; line-height: 1.4;
}
.viewas-tag {
  flex: none;
  background: var(--warn); color: #fff;
  border-radius: 4px; padding: 2px 8px;
  font-size: .68rem; font-weight: 800; letter-spacing: .08em;
}
.viewas-who { color: #fff; }
.viewas-who strong { color: #fff; }
.viewas-note { color: #C9D6D0; font-size: .8rem; }
.viewas-exit {
  margin-left: auto;
  background: #fff; color: var(--ink); border-color: #fff;
}
.viewas-exit:hover { background: #F1F5F3; }

/* Sit the normal header under the bar rather than behind it. Harmless when
   the bar is absent: --viewas-h is unset, so this falls back to 0. */
body.has-viewas .topbar { top: var(--viewas-h, 0px); }

/* ── tap-ready ─────────────────────────────────────────────────────────────
   A code on a screen is a link. These are the few places that shows. */
.hero-link { display: block; line-height: 0; border-radius: 14px; }
.hero-link:focus-visible { outline: 3px solid var(--emerald); outline-offset: 6px; }
.tap-hint { margin-top: 6px; color: #B9CCC4; }
.tap-hint strong { color: var(--emerald); }
a.code-thumb { cursor: pointer; transition: box-shadow .12s ease, border-color .12s ease; }
a.code-thumb:hover, a.code-thumb:focus-visible { border-color: var(--forest); box-shadow: 0 0 0 3px rgba(27,67,50,.12); outline: none; }
.tap-card { border-color: #A7F3D0; }
.tap-preview {
  display: grid; place-items: center; padding: 22px 14px; border-radius: var(--r-lg);
  background: var(--cream); border: 1px solid var(--line); overflow: auto;
}
.tap-preview table { margin: 0 auto; }
.feature--wide {
  grid-column: 1 / -1; display: flex; gap: 18px; align-items: flex-start;
  background: #F2FBF7; border-color: #A7F3D0;
}
.feature--wide .feature-icon { flex: none; margin-bottom: 0; background: var(--forest); color: #fff; }
.feature--wide p { max-width: 86ch; }
@media (max-width: 620px) {
  .plan.featured { margin-top: 8px; }   /* room for the badge when plans stack */
  .feature--wide { flex-direction: column; gap: 12px; }
  .modal { padding: 20px 18px; }
  .modal .row { gap: 8px; }
  .modal .row .btn { flex: 1 1 auto; }
}

/* ── accessibility ─────────────────────────────────────────────────────────
   A way past the header for keyboard and screen-reader users, and no motion for
   people who have asked their system for less of it. */
.skip-link {
  position: absolute; left: 12px; top: -60px; z-index: 1000;
  background: var(--ink); color: #fff; padding: 10px 16px; border-radius: 8px; font-weight: 700;
}
.skip-link:focus { top: 12px; outline: 3px solid var(--emerald); }
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important; animation-iteration-count: 1 !important;
    transition-duration: .01ms !important; scroll-behavior: auto !important;
  }
}

/* ── footer on every app page ───────────────────────────────────────────── */
.app-footer { padding: 26px 0 34px; border-top: 1px solid var(--line); margin-top: 40px; }
.legal-links { display: flex; flex-wrap: wrap; gap: 6px 18px; }
.legal-links a { color: inherit; text-decoration: underline; text-underline-offset: 3px; }
.dark .legal-links a { color: #C9D6D0; }

/* ── policy pages ──────────────────────────────────────────────────────── */
.legal { max-width: 760px; margin: 0 auto; padding: 34px 20px 10px; }
.legal h1 { font-size: 2rem; letter-spacing: -.02em; margin: 0 0 6px; }
.legal h2 { font-size: 1.25rem; margin: 34px 0 8px; scroll-margin-top: 80px; }
.legal h3 { font-size: 1.02rem; margin: 20px 0 6px; }
.legal p, .legal li { line-height: 1.65; }
.legal ul, .legal ol { padding-left: 1.3em; }
.legal .meta { color: var(--muted); font-size: .9rem; margin: 0 0 22px; }
.legal .draft { background: #FFFBEB; border: 1px solid #FDE68A; color: #92400E; border-radius: 10px; padding: 10px 14px; font-size: .9rem; margin: 0 0 22px; }
.legal .toc { background: var(--cream); border: 1px solid var(--line); border-radius: 12px; padding: 12px 18px; font-size: .92rem; }
.legal .toc ol { margin: 6px 0 0; columns: 2; }
.legal table { width: 100%; border-collapse: collapse; font-size: .92rem; margin: 10px 0; }
.legal th, .legal td { text-align: left; vertical-align: top; padding: 8px 10px; border-bottom: 1px solid var(--line); }
.legal .box { border: 2px solid var(--forest); border-radius: 12px; padding: 14px 18px; margin: 14px 0; background: #fff; }
@media (max-width: 640px) { .legal .toc ol { columns: 1; } }

/* ── renewal consent at checkout ──────────────────────────────────────────── */
.consent { border: 1px solid var(--line); border-radius: 12px; padding: 12px 14px; margin-top: 14px; background: var(--cream); }
.consent dl { margin: 0 0 10px; display: grid; grid-template-columns: max-content 1fr; gap: 4px 14px; font-size: .9rem; }
.consent dt { color: var(--muted); }
.consent dd { margin: 0; }
.consent label { display: flex; gap: 10px; align-items: flex-start; font-size: .88rem; line-height: 1.5; cursor: pointer; }
.consent input[type=checkbox] { margin-top: 3px; width: 18px; height: 18px; flex: none; }


/* ── scans screen (app.js showStats) ───────────────────────────────────── */
.scan-tiles { grid-template-columns: repeat(2, 1fr) !important; }   /* 2x2 even on a phone */
.scan-chart { justify-content: space-between; }
.scan-chart i { max-width: 36px; cursor: default; }      /* a lone day is a bar, never a full-width block */
.scan-chart i:hover { background: var(--emerald-d); }
.scan-axis { position: relative; height: 1.3em; margin-top: 4px; }
.scan-axis span { position: absolute; top: 0; transform: translateX(-50%); font-size: .7rem; color: var(--muted); white-space: nowrap; }
.brk-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); gap: 12px; }
.brk { padding: 14px 16px; }
.brk-h { font-size: .78rem; text-transform: uppercase; letter-spacing: .05em; color: var(--muted); font-weight: 700; margin: 0 0 10px; }
.brk-row { display: grid; grid-template-columns: 1fr auto; column-gap: 10px; align-items: baseline; margin-bottom: 9px; font-size: .88rem; }
.brk-l { min-width: 0; overflow-wrap: anywhere; }
.brk-n { color: var(--muted); font-variant-numeric: tabular-nums; white-space: nowrap; }
.brk-bar { grid-column: 1 / -1; height: 4px; margin-top: 3px; background: #DCE6E1; }
.scan-table { max-height: 260px; overflow-y: auto; }
.scan-table th { position: sticky; top: 0; background: #fff; }
@media (max-width: 620px) {
  .scan-tiles .stat { padding: 12px 14px; }
  .scan-tiles .stat-num { font-size: 1.35rem; }
}
