/* eG Codes — design system.
   One stylesheet for the marketing site, the studio and the admin console, so a
   colour 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 grey 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; font-weight: 800; letter-spacing: -.02em; color: var(--ink); font-size: 1.06rem; }
.brand:hover { text-decoration: none; }
.brand-mark { width: 28px; height: 28px; flex: none; border-radius: 7px; }
.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 colour; only real links get the accent treatment. */
.dark a:not(.btn) { color: var(--emerald); }

/* 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 */
.price-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 18px; align-items: stretch; }
.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);
  background:
    linear-gradient(45deg, #F2F5F4 25%, transparent 25%) -10px 0/20px 20px,
    linear-gradient(-45deg, #F2F5F4 25%, transparent 25%) -10px 0/20px 20px,
    linear-gradient(45deg, transparent 75%, #F2F5F4 75%) 0 0/20px 20px,
    linear-gradient(-45deg, transparent 75%, #F2F5F4 75%) 0 0/20px 20px,
    #fff;
  border: 1px solid var(--line); min-height: 300px;
}
.preview-stage svg { width: min(360px, 100%); height: auto; display: block; }

.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); }

.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; }

.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, .price-grid { 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, .price-grid { 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; }
  .navlinks { gap: 0; }
  .navlinks a { padding: 7px 9px; font-size: .84rem; }
}


/* ── 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); }
