/* DnD Gadgets design system.
 *
 * Hand-authored custom properties rather than a utility framework, which is a
 * deliberate fit to what these tools are. alfred-gateway's shared base is 161
 * lines of pure CSS variables with no Tailwind in it, and each tool carries
 * its own <style> block. Tailwind was doing very little work here, so paying a
 * build-step tax for it would be a poor trade.
 *
 * Twelve tools previously had five unrelated palettes — wine, cream parchment,
 * slate, ink, warm gold — because each was designed to be told apart on a DM's
 * second monitor. That recognition is worth keeping, so a tool sets ONE hue
 * (--gg-accent-h) and inherits everything else. One system, twelve identities.
 */

/* ---------------------------------------------------------------- tokens */
:root {
    color-scheme: dark;

    /* Surface ramp. Dark by default: used in dim rooms, at night, beside a
       laptop that should not light up the table. */
    --gg-bg:          #0E1116;
    --gg-surface-1:   #161A21;
    --gg-surface-2:   #1E242D;
    --gg-surface-3:   #262E39;
    --gg-border:      #2C3542;
    --gg-border-soft: rgba(255, 255, 255, 0.08);

    /* Text, contrast-checked against --gg-surface-1. */
    --gg-text:        #E6EAF0;   /* 13.1:1 */
    --gg-text-muted:  #A6B0BE;   /*  6.8:1 */
    --gg-text-faint:  #767F8C;   /*  4.6:1 — AA for body text */

    /* Per-tool accent. A tool overrides --gg-accent-h and nothing else. */
    --gg-accent-h: 220;
    --gg-accent-s: 62%;
    --gg-accent:        hsl(var(--gg-accent-h) var(--gg-accent-s) 62%);
    --gg-accent-dim:    hsl(var(--gg-accent-h) var(--gg-accent-s) 44%);
    --gg-accent-bg:     hsl(var(--gg-accent-h) var(--gg-accent-s) 62% / 0.12);
    --gg-accent-border: hsl(var(--gg-accent-h) var(--gg-accent-s) 62% / 0.45);
    --gg-accent-ring:   hsl(var(--gg-accent-h) var(--gg-accent-s) 62% / 0.55);

    /* Semantic colours are fixed across tools so they never mean two things. */
    --gg-ok:   #7FB08A;
    --gg-warn: #D9A441;
    --gg-bad:  #D4604E;

    /* One serif for content, one UI stack, one mono. Seven families across
       thirteen templates meant two render-blocking third-party requests per
       page load. */
    --gg-font: "Spectral", Georgia, "Times New Roman", serif;
    --gg-font-ui: ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;
    --gg-font-mono: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;

    --gg-text-xs:   0.75rem;
    --gg-text-sm:   0.875rem;
    --gg-text-base: 1rem;
    --gg-text-lg:   1.125rem;
    --gg-text-xl:   1.375rem;
    --gg-text-2xl:  1.75rem;
    --gg-text-3xl:  2.25rem;

    --gg-space-1: 0.25rem;
    --gg-space-2: 0.5rem;
    --gg-space-3: 0.75rem;
    --gg-space-4: 1rem;
    --gg-space-6: 1.5rem;
    --gg-space-8: 2rem;

    --gg-radius:    0.5rem;
    --gg-radius-sm: 0.375rem;

    --gg-shadow: 0 4px 16px rgb(0 0 0 / 0.35);

    /* Everything fixed or sticky offsets from this, so the top bar and a
       tool's own sticky controls can never overlap. */
    --gg-topbar-h: 3.5rem;

    /* 44px. Non-negotiable: these are used one-handed, at a table. */
    --gg-tap: 2.75rem;
}

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

body {
    margin: 0;
    background: var(--gg-bg);
    color: var(--gg-text);
    font-family: var(--gg-font-ui);
    line-height: 1.5;
    -webkit-text-size-adjust: 100%;
}

h1, h2, h3 { font-family: var(--gg-font); line-height: 1.2; margin: 0 0 var(--gg-space-3); }
h1 { font-size: var(--gg-text-3xl); }
h2 { font-size: var(--gg-text-xl); }
p  { margin: 0 0 var(--gg-space-3); }
a  { color: var(--gg-accent); }

/* One focus treatment everywhere: keyboard users get a ring, mouse users do
   not get a stray outline on click. */
:focus-visible {
    outline: 2px solid var(--gg-accent-ring);
    outline-offset: 2px;
    border-radius: var(--gg-radius-sm);
}

[hidden] { display: none !important; }

/* ---------------------------------------------------------------- chrome */
.gg-topbar {
    position: sticky; top: 0; z-index: 50;
    height: var(--gg-topbar-h);
    display: flex; align-items: center; gap: var(--gg-space-3);
    padding: 0 var(--gg-space-4);
    background: color-mix(in srgb, var(--gg-surface-1) 92%, transparent);
    backdrop-filter: blur(8px);
    border-bottom: 1px solid var(--gg-border);
}
.gg-brand {
    font-family: var(--gg-font); font-weight: 700;
    color: var(--gg-text); text-decoration: none; white-space: nowrap;
}
.gg-spacer { margin-left: auto; }

.gg-switcher { position: relative; }
.gg-switcher-list {
    position: absolute; top: calc(100% + var(--gg-space-2)); left: 0;
    min-width: 18rem; max-height: 70vh; overflow-y: auto;
    background: var(--gg-surface-2);
    border: 1px solid var(--gg-border);
    border-radius: var(--gg-radius);
    box-shadow: var(--gg-shadow);
    padding: var(--gg-space-2);
    z-index: 60;
}
.gg-switcher-group {
    font-size: var(--gg-text-xs); text-transform: uppercase;
    letter-spacing: 0.12em; color: var(--gg-text-faint);
    padding: var(--gg-space-2) var(--gg-space-2) var(--gg-space-1);
}
.gg-switcher-item {
    display: flex; align-items: center; gap: var(--gg-space-2);
    min-height: var(--gg-tap);
    padding: var(--gg-space-2);
    border-radius: var(--gg-radius-sm);
    color: var(--gg-text); text-decoration: none;
}
.gg-switcher-item:hover { background: var(--gg-surface-3); }
.gg-switcher-item[aria-current="page"] { background: var(--gg-accent-bg); }
.gg-dot {
    width: .5rem; height: .5rem; border-radius: 999px; flex-shrink: 0;
    background: hsl(var(--item-h, 220) 62% 62%);
}

/* ------------------------------------------------------------ components */
.gg-shell {
    max-width: 58rem; margin: 0 auto;
    padding: var(--gg-space-6) var(--gg-space-4);
    padding-bottom: calc(var(--gg-space-8) + env(safe-area-inset-bottom));
}

.gg-btn {
    display: inline-flex; align-items: center; justify-content: center;
    gap: var(--gg-space-2);
    min-height: var(--gg-tap);
    padding: 0 var(--gg-space-4);
    font: inherit; font-weight: 600;
    color: var(--gg-text);
    /* The marketing pages render buttons as <a>. Inside the app they are all
       real <button>s, so the inherited link underline never showed up until
       there was a public page. */
    text-decoration: none;
    background: var(--gg-surface-3);
    border: 1px solid var(--gg-border);
    border-radius: var(--gg-radius-sm);
    cursor: pointer;
    transition: background-color .15s, border-color .15s, transform .1s;
}
.gg-btn:hover:not(:disabled) { background: var(--gg-surface-2); border-color: var(--gg-accent-border); }
.gg-btn:active:not(:disabled) { transform: translateY(1px); }
.gg-btn:disabled { opacity: .45; cursor: not-allowed; }

.gg-btn--primary { background: var(--gg-accent-dim); border-color: var(--gg-accent); color: #fff; }
.gg-btn--primary:hover:not(:disabled) { filter: brightness(1.12); background: var(--gg-accent-dim); }
.gg-btn--ghost { background: transparent; }
/* One size up, for the handful of buttons a page is actually built around. */
.gg-btn--lg {
    min-height: 3.25rem;
    padding: 0 var(--gg-space-6);
    font-size: var(--gg-text-lg);
}

/* Wraps one or more axis groups. Fumble Tables has two (side, attack) and
   they had no spacing between them, because this class was referenced by the
   shared macro and never defined. */
.gg-selector { display: grid; gap: var(--gg-space-3); margin-bottom: var(--gg-space-4); }

.gg-segmented { display: flex; flex-wrap: wrap; gap: var(--gg-space-1); }
.gg-segmented .gg-btn { flex: 1 1 auto; min-width: 5rem; }
.gg-segmented .gg-btn[aria-pressed="true"] {
    background: var(--gg-accent-bg); border-color: var(--gg-accent);
}
.gg-segmented .gg-btn:disabled { text-decoration: line-through; }

.gg-card {
    background: var(--gg-surface-1);
    border: 1px solid var(--gg-border);
    border-radius: var(--gg-radius);
    padding: var(--gg-space-4);
}

.gg-input {
    width: 100%; min-height: var(--gg-tap);
    padding: 0 var(--gg-space-3);
    font: inherit; color: var(--gg-text);
    background: var(--gg-surface-2);
    border: 1px solid var(--gg-border);
    border-radius: var(--gg-radius-sm);
}
.gg-input::placeholder { color: var(--gg-text-faint); }

/* Flashed messages. The variant is carried by a word in the text as well as
   by the border colour — "Nothing was deleted" reads the same to everyone. */
.gg-notice {
    padding: var(--gg-space-3) var(--gg-space-4);
    margin-bottom: var(--gg-space-4);
    background: var(--gg-surface-1);
    border: 1px solid var(--gg-border);
    border-left-width: 3px;
    border-radius: var(--gg-radius-sm);
}
.gg-banner {
    border-bottom: 1px solid var(--gg-border);
    background: var(--gg-surface-1);
    font-size: var(--gg-text-sm);
}
.gg-banner-inner {
    display: flex; align-items: center; gap: var(--gg-space-3);
    flex-wrap: wrap;
    padding: var(--gg-space-3) var(--gg-space-4);
}
.gg-banner-label {
    text-transform: uppercase; letter-spacing: .08em;
    font-size: var(--gg-text-xs);
}
.gg-banner--warn  { border-bottom-color: var(--gg-warn); }
.gg-banner--warn  .gg-banner-label { color: var(--gg-warn); }
.gg-banner--error { border-bottom-color: var(--gg-bad); }
.gg-banner--error .gg-banner-label { color: var(--gg-bad); }

.gg-notice--ok    { border-left-color: var(--gg-ok); }
.gg-notice--error { border-left-color: var(--gg-bad); }

.gg-muted { color: var(--gg-text-muted); }
.gg-faint { color: var(--gg-text-faint); font-size: var(--gg-text-sm); }
.gg-mono  { font-family: var(--gg-font-mono); }

.gg-banner {
    display: flex; align-items: center; gap: var(--gg-space-2);
    padding: var(--gg-space-3) var(--gg-space-4);
    border-radius: var(--gg-radius-sm);
    border: 1px solid var(--gg-accent-border);
    background: var(--gg-accent-bg);
    margin-bottom: var(--gg-space-4);
}
.gg-banner--bad { border-color: var(--gg-bad); background: rgb(212 96 78 / .12); }

/* ----------------------------------------------------------- the roller */
/* Shared by every table tool, so markup and CSS live in one place rather than
   five near-identical copies with five different id prefixes. */
.gg-roll-row { text-align: center; margin-bottom: var(--gg-space-6); }
.gg-roll-hint { color: var(--gg-text-faint); font-size: var(--gg-text-xs); margin-top: var(--gg-space-2); }

.gg-result {
    border: 1px solid var(--gg-border);
    border-left: 4px solid var(--gg-tier, var(--gg-accent));
    border-radius: var(--gg-radius);
    background: var(--gg-surface-1);
    padding: var(--gg-space-4);
    margin-bottom: var(--gg-space-6);
    animation: gg-rise .3s ease-out;
}
.gg-result-head {
    display: flex; align-items: baseline; flex-wrap: wrap;
    gap: var(--gg-space-3); margin-bottom: var(--gg-space-2);
}
.gg-result-roll {
    font-family: var(--gg-font-mono);
    font-size: var(--gg-text-3xl); font-weight: 700; line-height: 1;
    color: var(--gg-tier, var(--gg-accent));
}
.gg-badge {
    font-size: var(--gg-text-xs); text-transform: uppercase; letter-spacing: .12em;
    padding: .2rem .5rem; border-radius: 999px;
    color: var(--gg-tier, var(--gg-accent));
    border: 1px solid color-mix(in srgb, var(--gg-tier, var(--gg-accent)) 55%, transparent);
    background: color-mix(in srgb, var(--gg-tier, var(--gg-accent)) 14%, transparent);
}
.gg-result-name { font-size: var(--gg-text-xl); font-weight: 700; margin: 0 0 var(--gg-space-2); }
.gg-result-body { color: var(--gg-text-muted); margin: 0; }

.gg-row {
    display: flex; gap: var(--gg-space-3);
    padding: var(--gg-space-3);
    border-top: 1px solid var(--gg-border-soft);
    border-left: 3px solid var(--gg-tier, transparent);
}
.gg-row-roll {
    font-family: var(--gg-font-mono); font-weight: 700;
    color: var(--gg-tier, var(--gg-text-muted));
    min-width: 2.4rem; text-align: right; flex-shrink: 0;
}
.gg-row-name { font-weight: 600; }
.gg-row-body { color: var(--gg-text-muted); font-size: var(--gg-text-sm); }
/* The tier is NAMED here, never conveyed by colour alone. The severity ramp
   runs grey -> steel -> violet -> brass -> rust, which is precisely the axis
   red-green colour deficiency collapses. */
.gg-row-tier {
    font-size: var(--gg-text-xs); text-transform: uppercase;
    letter-spacing: .1em; color: var(--gg-text-faint); margin-top: .15rem;
}

.gg-panel { margin-bottom: var(--gg-space-4); }
.gg-panel-toggle {
    display: flex; align-items: center; gap: var(--gg-space-2); width: 100%;
    min-height: var(--gg-tap);
    font: inherit; font-size: var(--gg-text-sm);
    text-transform: uppercase; letter-spacing: .1em;
    color: var(--gg-text-muted);
    background: var(--gg-surface-1);
    border: 1px solid var(--gg-border);
    border-radius: var(--gg-radius-sm);
    padding: 0 var(--gg-space-3);
    cursor: pointer;
}
.gg-panel-body {
    border: 1px solid var(--gg-border); border-top: none;
    border-radius: 0 0 var(--gg-radius-sm) var(--gg-radius-sm);
    max-height: 26rem; overflow-y: auto;
}
.gg-panel-empty { padding: var(--gg-space-4); text-align: center; color: var(--gg-text-faint); }

@keyframes gg-rise {
    from { opacity: 0; transform: translateY(8px); }
    to   { opacity: 1; transform: translateY(0); }
}

/* Honour the setting rather than treating motion as decoration. The dice
   roller reads this too, and skips the physics tumble entirely. */
@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after {
        animation-duration: .01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: .01ms !important;
    }
}

@media (max-width: 40rem) {
    :root { --gg-text-3xl: 1.875rem; }
    .gg-shell { padding: var(--gg-space-4) var(--gg-space-3); }
    .gg-segmented .gg-btn { min-width: 4rem; }
}

/* ==========================================================================
   Marketing
   Only the public pages use any of this. It is appended rather than mixed
   into the app tokens above so that deleting the marketing site would be a
   clean cut, and so nothing here can be mistaken for a shared component.
   ========================================================================== */

.mk-hero {
    padding: var(--gg-space-8) var(--gg-space-4) 0;
    text-align: center;
}
.mk-hero h1 {
    font-size: clamp(2rem, 6vw, 3.5rem);
    line-height: 1.1;
    margin: 0 0 var(--gg-space-4);
    letter-spacing: -0.02em;
}
.mk-hero .mk-sub {
    font-size: var(--gg-text-lg);
    color: var(--gg-text-muted);
    max-width: 40rem;
    margin: 0 auto var(--gg-space-6);
}
.mk-cta { display: flex; gap: var(--gg-space-3); justify-content: center; flex-wrap: wrap; }

/* "Card required" is deliberately adjacent to the CTA and not in a footnote.
   Burying it is how you earn chargebacks and one-star reviews. */
.mk-cta-note {
    margin-top: var(--gg-space-3);
    font-size: var(--gg-text-sm);
    color: var(--gg-text-faint);
}

/* --- Device mockups ------------------------------------------------------
   Pure CSS frames around real captures. The alternative is baking a frame
   into each PNG, which means re-editing twelve images every time a tool's
   design moves. This way `make shots` is the only step.
   The aspect ratios match the capture viewports exactly (1280x800, 390x844),
   so nothing is ever letterboxed or stretched.
   -------------------------------------------------------------------------*/
.mk-stage {
    position: relative;
    max-width: 62rem;
    margin: var(--gg-space-8) auto 0;
    padding: 0 var(--gg-space-4);
}
.mk-laptop {
    position: relative;
    border: 0.6rem solid #2A313C;
    border-bottom-width: 0.9rem;
    border-radius: 0.9rem;
    background: #2A313C;
    box-shadow: 0 30px 70px rgb(0 0 0 / 0.55);
    overflow: hidden;
}
.mk-laptop img { display: block; width: 100%; height: auto; aspect-ratio: 1280 / 800; }
/* The foot. Decorative, so it is a pseudo-element and never announced. */
.mk-laptop::after {
    content: "";
    position: absolute; left: 50%; bottom: -0.45rem;
    width: 5rem; height: 0.25rem; transform: translateX(-50%);
    background: #3A4350; border-radius: 0 0 0.3rem 0.3rem;
}
.mk-phone {
    position: absolute;
    /* Hangs off the corner rather than sitting on top of the laptop. Further
       in and it covers the initiative rows, which are the point of the shot. */
    right: -0.5rem; bottom: -3.5rem;
    width: 11rem;
    border: 0.45rem solid #2A313C;
    border-radius: 1.6rem;
    background: #2A313C;
    box-shadow: 0 20px 45px rgb(0 0 0 / 0.6);
    overflow: hidden;
}
.mk-phone img { display: block; width: 100%; height: auto; aspect-ratio: 390 / 844; }
@media (max-width: 52rem) {
    /* Below this the phone overlaps the laptop's content rather than its
       margin, hiding the thing the hero is meant to show. */
    .mk-phone { display: none; }
}

.mk-section { padding: var(--gg-space-8) var(--gg-space-4); }
.mk-section h2 {
    font-size: clamp(1.5rem, 4vw, var(--gg-text-3xl));
    text-align: center;
    margin: 0 0 var(--gg-space-2);
}
.mk-section .mk-lede {
    text-align: center; color: var(--gg-text-muted);
    max-width: 38rem; margin: 0 auto var(--gg-space-8);
}

/* Shared by the marketing site and the in-app hub: the same twelve tools,
   the same per-tool accent, so they should look like the same twelve things.
   Named gg- rather than mk- for that reason. */
.gg-tool-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr));
    gap: var(--gg-space-4);
    max-width: 68rem; margin: 0 auto;
}
.gg-tool-card {
    display: block;
    padding: var(--gg-space-4);
    background: var(--gg-surface-1);
    border: 1px solid var(--gg-border);
    border-top: 3px solid hsl(var(--gg-card-h, 220) var(--gg-accent-s) 62%);
    border-radius: var(--gg-radius);
    color: inherit; text-decoration: none;
    transition: transform .12s ease, border-color .12s ease;
}
.gg-tool-card:hover { transform: translateY(-2px); border-color: var(--gg-border-soft); }
.gg-tool-card h3 { margin: 0 0 var(--gg-space-2); font-size: var(--gg-text-lg); }
.gg-tool-card p { margin: 0; color: var(--gg-text-muted); font-size: var(--gg-text-sm); }

/* A tier heading inside the tool grid. */
.gg-tier-label {
    max-width: 68rem;
    margin: var(--gg-space-8) auto var(--gg-space-4);
    color: var(--gg-text-faint);
    text-transform: uppercase;
    letter-spacing: .12em;
    font-size: var(--gg-text-xs);
}

/* Alternating deep-dive rows. */
.mk-deep {
    display: grid;
    grid-template-columns: 1fr 1.15fr;
    gap: var(--gg-space-8);
    align-items: center;
    max-width: 68rem;
    margin: 0 auto var(--gg-space-8);
}
.mk-deep:nth-child(even) .mk-deep-text { order: 2; }
.mk-deep img {
    width: 100%; height: auto;
    border-radius: var(--gg-radius);
    border: 1px solid var(--gg-border); box-shadow: var(--gg-shadow);
    /* Crop to the top of the capture. The shots are 1280x800 because that is
       the tool's own viewport, and most tools leave the bottom third empty —
       shown uncropped in a half-width column that empty third is the most
       eye-catching thing in the row. */
    aspect-ratio: 2 / 1;
    object-fit: cover;
    object-position: top center;
}
.mk-deep h3 { font-size: var(--gg-text-2xl); margin: 0 0 var(--gg-space-3); }
.mk-deep p { color: var(--gg-text-muted); margin: 0 0 var(--gg-space-3); }
@media (max-width: 48rem) {
    .mk-deep { grid-template-columns: 1fr; gap: var(--gg-space-4); }
    .mk-deep:nth-child(even) .mk-deep-text { order: 0; }
}

.mk-price {
    max-width: 24rem; margin: 0 auto; text-align: center;
    padding: var(--gg-space-8) var(--gg-space-6);
    background: var(--gg-surface-1);
    border: 1px solid var(--gg-accent-border);
    border-radius: var(--gg-radius);
}
.mk-price .mk-amount { font-size: 3rem; font-weight: 700; line-height: 1; }
.mk-price .mk-per { color: var(--gg-text-faint); }
.mk-price ul { list-style: none; padding: 0; margin: var(--gg-space-6) 0; text-align: left; }
.mk-price li {
    padding: var(--gg-space-2) 0;
    border-bottom: 1px solid var(--gg-border);
    /* Hang the tick, so a wrapped second line aligns under the text and not
       under the mark. */
    padding-left: 1.4em;
    text-indent: -1.4em;
}
.mk-price li::before { content: "✓ "; color: var(--gg-accent); font-weight: 700; }

.mk-faq { max-width: 44rem; margin: 0 auto; }
.mk-faq details {
    border-bottom: 1px solid var(--gg-border);
    padding: var(--gg-space-4) 0;
}
.mk-faq summary { cursor: pointer; font-weight: 600; }
.mk-faq summary:focus-visible { outline: 2px solid var(--gg-accent-ring); outline-offset: 3px; }
.mk-faq p { color: var(--gg-text-muted); margin: var(--gg-space-3) 0 0; }

.mk-footer {
    border-top: 1px solid var(--gg-border);
    padding: var(--gg-space-8) var(--gg-space-4);
    text-align: center;
}
.mk-footer p { margin: 0 0 var(--gg-space-3); font-size: var(--gg-text-sm); }

/* Legal pages: long prose, so constrain the measure. */
.mk-prose { max-width: 42rem; margin: 0 auto; padding: var(--gg-space-8) var(--gg-space-4); }
.mk-prose h1 { font-size: var(--gg-text-3xl); margin-bottom: var(--gg-space-2); }
.mk-prose h2 { font-size: var(--gg-text-xl); margin-top: var(--gg-space-8); }
.mk-prose p, .mk-prose li { color: var(--gg-text-muted); line-height: 1.7; }
/* The licence attribution contains two full URLs as link text, which is a
   licence requirement rather than a style choice, and they were pushing the
   page 44px wide at 360px. */
.mk-prose { overflow-wrap: anywhere; }
.mk-prose blockquote {
    margin: var(--gg-space-4) 0;
    padding: var(--gg-space-4);
    border-left: 3px solid var(--gg-accent-border);
    background: var(--gg-surface-1);
    border-radius: 0 var(--gg-radius-sm) var(--gg-radius-sm) 0;
}
.mk-prose blockquote p { margin: 0; font-size: var(--gg-text-sm); }

/* Width/height attributes are presentational hints and will pin an image's
   height if CSS never says otherwise, which both stretches the image and
   defeats any aspect-ratio set on it. Every image on a public page is sized
   by its container, so say it once. */
.mk-prose img, .mk-section img, .mk-hero img { height: auto; }

/* The public nav carries four items where the app's carries two, and at 390px
   the fourth was clipped off the right edge. Pricing is reachable from the
   landing page and the footer, so it is the one that goes. */
@media (max-width: 30rem) {
    .mk-nav-sm-hide { display: none; }
    .gg-topbar .gg-btn { padding: 0 var(--gg-space-3); }
}

/* ==========================================================================
   Auth
   The sign-in page is where someone decides whether this is a real product or
   somebody's weekend project, and it was the last unstyled surface in the app.
   Deliberately narrow and centred: there is exactly one decision to make here.
   ========================================================================== */

.au-wrap {
    min-height: 100dvh;
    display: grid;
    place-items: center;
    padding: var(--gg-space-6) var(--gg-space-4);
}
.au-card {
    width: 100%;
    max-width: 24rem;
    padding: var(--gg-space-8) var(--gg-space-6);
    background: var(--gg-surface-1);
    border: 1px solid var(--gg-border);
    border-radius: var(--gg-radius);
    box-shadow: var(--gg-shadow);
}
.au-brand {
    display: block;
    text-align: center;
    font-family: var(--gg-font);
    font-weight: 700;
    font-size: var(--gg-text-lg);
    color: var(--gg-text);
    text-decoration: none;
    margin-bottom: var(--gg-space-6);
}
.au-card h1 {
    font-size: var(--gg-text-2xl);
    text-align: center;
    margin: 0 0 var(--gg-space-2);
}
.au-lede {
    text-align: center;
    color: var(--gg-text-muted);
    font-size: var(--gg-text-sm);
    margin: 0 0 var(--gg-space-6);
}

/* Google's button is white-on-white by convention and people look for that
   exact shape. Deviating from it costs recognition for no gain. */
.au-google {
    display: flex; align-items: center; justify-content: center;
    gap: var(--gg-space-3);
    width: 100%;
    min-height: var(--gg-tap);
    padding: 0 var(--gg-space-4);
    font: inherit; font-weight: 600;
    color: #1F1F1F;
    background: #FFFFFF;
    border: 1px solid #DADCE0;
    border-radius: var(--gg-radius-sm);
    text-decoration: none;
    transition: background-color .15s, box-shadow .15s;
}
.au-google:hover { background: #F7F8F8; box-shadow: 0 1px 3px rgb(0 0 0 / .3); }
.au-google:focus-visible { outline: 2px solid var(--gg-accent-ring); outline-offset: 2px; }
.au-google svg { width: 1.15rem; height: 1.15rem; flex: none; }

/* A rule with a word in it, rather than a bare "or" floating in space. */
.au-or {
    display: flex; align-items: center; gap: var(--gg-space-3);
    margin: var(--gg-space-6) 0;
    color: var(--gg-text-faint);
    font-size: var(--gg-text-xs);
    text-transform: uppercase;
    letter-spacing: .12em;
}
.au-or::before, .au-or::after {
    content: ""; flex: 1; height: 1px; background: var(--gg-border);
}

.au-field { display: block; margin-bottom: var(--gg-space-3); }
.au-field label {
    display: block;
    margin-bottom: var(--gg-space-2);
    font-size: var(--gg-text-sm);
    color: var(--gg-text-muted);
}
.au-field .gg-input { width: 100%; }
.au-submit { width: 100%; }
.au-foot {
    margin: var(--gg-space-6) 0 0;
    text-align: center;
    font-size: var(--gg-text-sm);
    color: var(--gg-text-faint);
}
.au-foot a { color: var(--gg-text-muted); }

/* The "check your email" page: one fact, stated large. */
.au-icon {
    display: block; text-align: center;
    font-size: 2.5rem; line-height: 1;
    margin-bottom: var(--gg-space-4);
}
.au-email {
    display: block;
    margin: var(--gg-space-4) 0;
    padding: var(--gg-space-3);
    background: var(--gg-surface-2);
    border-radius: var(--gg-radius-sm);
    font-family: var(--gg-font-mono);
    font-size: var(--gg-text-sm);
    text-align: center;
    overflow-wrap: anywhere;
}

/* ==========================================================================
   Free tables
   1,560 hand-written rows, published ungated. These pages are the only thing
   on the site a stranger can actually use, so they get real typography rather
   than a dump of the data.
   ========================================================================== */

.tbl-page { max-width: 52rem; }          /* wider than prose — it holds a table */
.tbl-crumb { font-size: var(--gg-text-sm); color: var(--gg-text-faint); }
.tbl-crumb a { color: var(--gg-text-muted); }
.tbl-lede { font-size: var(--gg-text-lg); color: var(--gg-text-muted); }

.tbl-tiers { list-style: none; padding: 0; }
.tbl-tiers li {
    padding: var(--gg-space-2) 0;
    border-bottom: 1px solid var(--gg-border);
}
.tbl-range {
    font-family: var(--gg-font-mono);
    font-size: var(--gg-text-sm);
    color: var(--gg-text-faint);
    margin-left: var(--gg-space-2);
}

/* The table is the point of the page. Horizontally scrollable rather than
   squeezed, because 100 rows of four columns will not fit a phone otherwise
   and a cramped table is worse than one you swipe. */
.tbl-scroll { overflow-x: auto; -webkit-overflow-scrolling: touch; }
.tbl {
    width: 100%;
    border-collapse: collapse;
    font-size: var(--gg-text-sm);
}
.tbl th, .tbl td {
    padding: var(--gg-space-3);
    border-bottom: 1px solid var(--gg-border);
    text-align: left;
    vertical-align: top;
}
.tbl thead th {
    position: sticky; top: 0;
    background: var(--gg-surface-2);
    color: var(--gg-text-muted);
    font-size: var(--gg-text-xs);
    text-transform: uppercase;
    letter-spacing: .08em;
    border-bottom: 2px solid var(--gg-border);
}
.tbl tbody tr:hover { background: var(--gg-surface-1); }
.tbl-roll {
    font-family: var(--gg-font-mono);
    font-weight: 700;
    color: var(--gg-accent);
    white-space: nowrap;
}
.tbl-name { font-weight: 600; color: var(--gg-text); white-space: nowrap; }
/* Tier is a WORD in its own column, never a colour alone — same rule the
   in-app tables follow, for the same red-green reason. */
.tbl-tier {
    font-size: var(--gg-text-xs);
    text-transform: uppercase;
    letter-spacing: .06em;
    color: var(--gg-text-faint);
    white-space: nowrap;
}

.tbl-q { font-size: var(--gg-text-lg); margin-top: var(--gg-space-6); }

.tbl-cta {
    margin: var(--gg-space-8) 0;
    padding: var(--gg-space-6);
    background: var(--gg-surface-1);
    border: 1px solid var(--gg-accent-border);
    border-radius: var(--gg-radius);
}
.tbl-cta h2 { margin-top: 0; }
.tbl-cta .gg-btn { margin-right: var(--gg-space-2); }

.tbl-siblings, .tbl-index { list-style: none; padding: 0; }
.tbl-siblings li, .tbl-index li {
    padding: var(--gg-space-2) 0;
    border-bottom: 1px solid var(--gg-border);
    display: flex; gap: var(--gg-space-3); justify-content: space-between;
    flex-wrap: wrap;
}
