/* ============================================================
 *  LavaBot - style v2 (OVERRIDE LAYER)  ·  rev 2: bands, not islands
 *
 *  Loaded AFTER style.css when SITE_THEME=v2. Still an override layer, so
 *  nothing is deleted and SITE_THEME=legacy restores the old design intact.
 *
 *  WHY REV 2 EXISTS
 *  Rev 1 kept the legacy skeleton and only retuned colour and spacing. That
 *  left the thing that actually dates the site: every piece of content sits
 *  in its own bordered, faintly glossy box, floating in the middle of a dark
 *  page. A screen of those reads as a spreadsheet of tiles no matter how
 *  nice the tokens are.
 *
 *  Rev 2 removes the box as the unit of layout.
 *    - CONTENT SITS ON THE PAGE, not in a card on the page. No border, no
 *      panel background, no shadow, no inner highlight.
 *    - SECTIONS ARE FULL-BLEED BANDS. They span edge to edge and are told
 *      apart by a change in ground tone and by generous vertical air, never
 *      by a rule or a rounded rectangle.
 *    - LISTS ARE ROWS. Settings, stats and records are hairline-separated
 *      rows across the content column, which is how a dense settings screen
 *      is meant to read (the Sapphire lesson) rather than a grid of tiles.
 *    - NOTHING IS GLOSSY. No vertical sheen gradients, no inset white
 *      highlights, no drop shadows. Matte basalt.
 *
 *  LAVA BUDGET: 3. The animated magma veins are gone, they read as
 *  decoration bolted onto a banner. What is left is structural: the ember
 *  sweep on a primary action, the molten edge on the active nav item, and
 *  the fused rule on the two top plans.
 * ============================================================ */

/* ──────────────────────────────────────────────────────────
 *  Tokens
 * ────────────────────────────────────────────────────────── */
:root {
  /* Basalt ramp. Warm-shadowed neutrals, lifted off pure black: a page at
     #0c0b0d has nowhere left to go darker, so every surface has to be built
     UP with light, which is what produced the glossy panels. Starting at a
     soft near-black leaves room to recede as well as rise. */
  --rock-950: #100e13;   /* deepest, footer only */
  --rock-900: #17151a;   /* page ground */
  --rock-850: #1d1a22;   /* alternate band */
  --rock-800: #24202b;   /* raised */
  --rock-700: #2c2733;
  --ash-400: #a9a3b0;

  /* Ember, pulled back from neon toward terracotta. #ff6600 is a signal
     colour: at full saturation across buttons, borders, badges and markers
     it reads as a warning, not as a brand. These sit in the same hue family
     with the saturation taken off, so orange can appear often without
     shouting. */
  --ember-600: #ff6600;  /* primary action */
  --ember-500: #ff6600;  /* accent */
  --ember-300: #ff6600;  /* light, on dark only */

  /* Hairline. The ONLY separator in the system: no boxes, no panel borders. */
  --hair: rgba(201, 193, 210, 0.13);
  --hair-strong: rgba(201, 193, 210, 0.2);

  /* Legacy names remapped so untouched components follow along. */
  --bg-0: var(--rock-900);
  --bg-1: var(--rock-850);
  --bg-2: var(--rock-800);
  --surface: transparent;
  --surface-strong: transparent;
  --line: var(--hair);
  --line-strong: rgba(255, 102, 0, 0.34);
  --text: #f4f1f5;
  --text-muted: var(--ash-400);
  --c-primary: var(--ember-600);
  --c-secondary: var(--ember-500);

  /* Radii stay differentiated, but now they apply to controls only, because
     almost nothing else is a rectangle any more. */
  --r-control: 8px;
  --r-pill: 999px;

  --col: min(1180px, 92vw);         /* the content column inside every band */
  --band-y: clamp(32px, 4.2vw, 68px); /* vertical air inside each band */
  --ease-out: cubic-bezier(0.22, 1, 0.36, 1);
}

/* ──────────────────────────────────────────────────────────
 *  Ground
 * ────────────────────────────────────────────────────────── */
body {
  background-color: var(--rock-900);
  /* No glow, no bloom, no coloured haze. The page ground is a flat colour.
     Two radial washes used to sit here: they are the "glow with no reason"
     from the anti-AI list, and they were also the reason the whole page had
     a faint orange cast that made the ember accents harder to see. Depth
     comes from the band tones now, which is a structural cue rather than a
     decorative one. */
  background-image: none;
  color: var(--text);
}

/* ──────────────────────────────────────────────────────────
 *  BANDS
 *
 *  Every top-level section becomes a full-bleed band. The legacy markup
 *  wraps content in .card / .section-shell, so those are stripped of their
 *  box here and re-cast as bands. Alternate bands take a slightly deeper
 *  ground, which is what separates them: no rules, no rounded edges.
 * ────────────────────────────────────────────────────────── */
.section-shell,
.card,
.lb-hero, .lb-features, .lb-pricing {
  background: none;
  background-color: transparent;
  border: 0;
  border-radius: 0;
  box-shadow: none;
  backdrop-filter: none;
}

/* Full-bleed band with an inner content column. Breaks out of whatever the
   parent container is doing using viewport units. */
.section-shell,
.lb-hero, .lb-features, .lb-pricing {
  width: 100vw;
  max-width: 100vw;
  margin-inline: calc(50% - 50vw);
  padding-block: var(--band-y);
  padding-inline: max(calc(50vw - var(--col) / 2), 20px);
}

/* Bands must TOUCH. The legacy sheet puts a margin between sections, which
   leaves a strip of page showing through and turns each band back into a
   floating slab. Flush edges are what make the tone change itself read as
   the separator. */
.section-shell,
.lb-hero, .lb-features, .lb-pricing {
  margin-block: 0;
}

/* The page shell is a grid with a 16px row gap, which shows a strip of page
   between every band and undoes the flush edge. Bands carry their own
   vertical air now, so the gap has nothing left to do. */
.main-shell { row-gap: 0; }

/* ONE ground colour, the darkest. Alternating two near-blacks produced a
   visible horizontal seam at every band edge, which is the boxed look
   coming back in through the floor. Sections are separated by air and by a
   hairline where one is genuinely needed, never by a change of shade. */
.section-shell,
.section-shell:nth-of-type(even),
.lb-hero, .lb-features, .lb-pricing {
  background-color: var(--rock-900);
}

/* ──────────────────────────────────────────────────────────
 *  Cards become rows
 *
 *  .card is the most common wrapper in the codebase (115 uses in the
 *  dashboard alone). Rather than restyle the box, it stops being a box: a
 *  block of content with air around it and a hairline above, so a column of
 *  them reads as a continuous document.
 * ────────────────────────────────────────────────────────── */
.card {
  padding: clamp(18px, 2.4vw, 30px) 0;
  border-top: 1px solid var(--hair);
}

.card:first-child,
.dash-grid > .card:nth-child(1),
.dash-grid > .card:nth-child(2) { border-top: 0; }

.card:hover { border-color: var(--hair); }   /* no hover box, it is not a box */

/* The dashboard grid stops being a grid of tiles. One column, rows stacked,
   which is what a settings screen actually is. */
.dash-grid { display: block; gap: 0; }

.card.full { grid-column: auto; }

/* A card heading is a row label, not a panel title. */
.card h2 {
  font-size: var(--fs-lg);
  letter-spacing: -0.02em;
  margin: 0 0 4px;
}

.center-card {
  max-width: 420px;
  margin-inline: auto;
  padding: 0;
  border-top: 0;
}

/* ──────────────────────────────────────────────────────────
 *  Typography
 * ────────────────────────────────────────────────────────── */
body, button, input, select, textarea {
  font-family: "Geist", system-ui, -apple-system, "Segoe UI", sans-serif;
}

code, kbd, samp, pre,
.cmd-name, .mono, .stat-value, .an-num, .dash-stat-value {
  font-family: "Geist Mono", ui-monospace, "SF Mono", Menlo, monospace;
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.01em;
}

h1, h2, h3 { letter-spacing: -0.028em; text-wrap: balance; }

h1 { font-size: clamp(1.9rem, 1.3rem + 2.6vw, 3.1rem); line-height: 1.05; }
h2 { font-size: clamp(1.3rem, 1.05rem + 1.1vw, 1.9rem); line-height: 1.15; }

/* Long-form text gets a measure. Full-width prose is unreadable on a wide
   screen, and it is the other half of why the old layout needed boxes. */
.section-shell p, .card p, .lede { max-width: 68ch; }

/* Body prose is content, so it gets the full text colour. The legacy sheet
   painted every <p> in the muted grey, which is why whole pages read as
   greyed out. Muted is reserved for things that ARE secondary: captions,
   helper text, the footer. */
p, li, dd, .section-shell p, .card p { color: var(--text); }

/* The legacy sheet colours list items per component (.support-list li,
   .changelog-entry ul li, .roadmap-list li ...), which outranks the bare
   `li` above. These are body copy, so they take the body colour; only the
   genuinely secondary lists keep the muted grey. */
.support-list li,
.changelog-entry ul li,
.roadmap-list li,
.section-shell ul li,
.section-shell ol li,
.card ul li,
.card ol li { color: var(--text); }
.muted, .small.muted, .muted.small, .hint, figcaption, .site-footer,
.site-footer p, .stat-label { color: var(--ash-400); }

/* No gradient text: contrast cost, and one of the clearest generated-design
   tells. Undo it wherever the legacy sheet applies it. */
.lb-hot, .grad-text, .hero h1 span, .brand-name {
  background: none !important;
  -webkit-background-clip: border-box !important;
  background-clip: border-box !important;
  -webkit-text-fill-color: currentColor !important;
  color: var(--ember-500);
}

/* ──────────────────────────────────────────────────────────
 *  Lists stop being boxes
 *
 *  The legacy sheet gives every list item its own bordered, filled,
 *  rounded rectangle. A page of those is the "islands floating in the
 *  middle" problem in its purest form: eight little panels where there
 *  should be one readable list. Same treatment as .card, they become rows
 *  separated by a hairline, with the marker sitting in the margin instead
 *  of inside a container.
 * ────────────────────────────────────────────────────────── */
.support-list,
.roadmap-list,
.changelog-entry ul,
.feature-list {
  display: block;
  gap: 0;
  padding: 0;
  margin: 14px 0 0;
  list-style: none;
}

.support-list li,
.roadmap-list li,
.changelog-entry ul li,
.feature-list li {
  padding: 11px 0 11px 22px;
  border: 0;
  border-top: 1px solid var(--hair);
  border-radius: 0;
  background: none;
  display: block;
  position: relative;
  max-width: 72ch;
}

.support-list li:first-child,
.roadmap-list li:first-child,
.changelog-entry ul li:first-child,
.feature-list li:first-child { border-top: 0; }

/* The marker is drawn, not typed: a 4px ember square in the left margin.
   A glyph here would depend on the stylesheet charset surviving every
   deploy, and it already got mangled once. A box cannot be mis-decoded,
   and it lines the text up flush down the page. */
.support-list li::before,
.roadmap-list li::before,
.changelog-entry ul li::before,
.feature-list li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 1.05em;
  width: 4px;
  height: 4px;
  border-radius: 1px;
  background: var(--ember-600);
}

/* ──────────────────────────────────────────────────────────
 *  Settings rows (the Sapphire pattern)
 *
 *  Label and description on the left, control hard right, hairline between
 *  rows. Dense, scannable, and it never turns into a tile.
 * ────────────────────────────────────────────────────────── */
.checkbox-line,
.feature-toggle,
.dash-row {
  display: flex;
  align-items: center;
  gap: 14px;
  width: 100%;
  margin: 0;
  padding: 13px 4px;
  border-top: 1px solid var(--hair);
  border-radius: 0;
  background: none;
  cursor: pointer;
  transition: background-color 0.14s var(--ease-out);
}

.checkbox-line:first-of-type,
.feature-toggle:first-of-type { border-top: 0; }

/* The hover tint bleeds past the content column so the row reads as a full
   band, not a highlighted rectangle. */
.checkbox-line:hover,
.feature-toggle:hover,
.dash-row:hover {
  background-color: rgba(255, 255, 255, 0.028);
  box-shadow: -14px 0 0 rgba(255, 255, 255, 0.028), 14px 0 0 rgba(255, 255, 255, 0.028);
}

.checkbox-line input[type="checkbox"] {
  width: auto;
  flex: 0 0 auto;
  margin-left: auto;          /* control sits at the end of the row */
  accent-color: var(--ember-600);
}

/* ──────────────────────────────────────────────────────────
 *  Stats: figures on the page, not tiles
 * ────────────────────────────────────────────────────────── */
.stat-card, .an-stat {
  background: none;
  border: 0;
  border-radius: 0;
  padding: 0 clamp(18px, 3vw, 40px) 0 0;
  display: inline-block;
}

.stat-value, .an-num {
  display: block;
  font-size: clamp(1.7rem, 1.2rem + 2vw, 2.7rem);
  font-weight: 600;
  line-height: 1;
  color: var(--text);
}

.stat-label, .an-stat .small {
  display: block;
  margin-top: 6px;
  color: var(--ash-400);
  font-size: var(--fs-xs);
  text-transform: uppercase;
  letter-spacing: 0.08em;
}

/* ──────────────────────────────────────────────────────────
 *  Controls
 * ────────────────────────────────────────────────────────── */
input[type="text"], input[type="email"], input[type="password"],
input[type="number"], input[type="search"], select, textarea {
  width: 100%;
  padding: 9px 12px;
  background: rgba(8, 8, 10, 0.6);
  border: 1px solid var(--hair);
  border-radius: var(--r-control);
  color: var(--text);
  font-size: var(--fs-sm);
  transition: border-color 0.16s var(--ease-out), background-color 0.16s var(--ease-out);
}

input:hover, select:hover, textarea:hover { border-color: var(--hair-strong); }

input:focus, select:focus, textarea:focus {
  border-color: var(--ember-600);
  background: rgba(8, 8, 10, 0.85);
  outline: none;
}

input::placeholder, textarea::placeholder { color: rgba(168, 162, 172, 0.55); }

/* A numeric field holds two or three digits; stretching it to the full row
   makes a threshold look like an essay box. */
input[type="number"] { width: auto; min-width: 5.5rem; max-width: 9rem; }
.checkbox-line input, .cta-pair input, .inline-field input { width: auto; }

.stacked-form { display: grid; gap: var(--space-3); }
.stacked-form label { font-size: var(--fs-sm); color: var(--text); }

.switch-track {
  background: rgba(196, 186, 200, 0.2);
  border-radius: var(--r-pill);
  transition: background-color 0.18s var(--ease-out);
}
.switch input:checked + .switch-track,
.switch-track[data-on="1"] { background: var(--ember-600); }

/* ──────────────────────────────────────────────────────────
 *  [LAVA 1] Primary action: ember sweep
 * ────────────────────────────────────────────────────────── */
.btn-primary {
  position: relative;
  overflow: hidden;
  border-radius: var(--r-control);
  background: var(--ember-600);
  border: 0;
  color: #170d02;
  font-weight: 620;
  isolation: isolate;
}

.btn-primary::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: linear-gradient(100deg, transparent 22%, rgba(255, 221, 173, 0.45) 50%, transparent 78%);
  transform: translateX(-120%);
  transition: transform 0.5s var(--ease-out);
}

.btn-primary:hover::after, .btn-primary:focus-visible::after { transform: translateX(120%); }

.btn-ghost {
  background: none;
  border: 1px solid var(--hair-strong);
  color: var(--text);
  border-radius: var(--r-control);
  font-weight: 520;
  transition: border-color 0.16s var(--ease-out), background-color 0.16s var(--ease-out);
}
.btn-ghost:hover { background: rgba(255, 255, 255, 0.05); border-color: rgba(196, 186, 200, 0.3); }

.btn-danger {
  background: none;
  border: 1px solid rgba(239, 83, 80, 0.4);
  color: #ff8a85;
  border-radius: var(--r-control);
}
.btn-danger:hover { background: rgba(239, 83, 80, 0.1); }

/* ──────────────────────────────────────────────────────────
 *  Navigation
 * ────────────────────────────────────────────────────────── */
.topbar {
  /* Solid, not frosted. Blur behind a sticky bar is glassmorphism and it
     repaints the blurred region on every scroll frame for no legibility
     gain on a dark ground. */
  background: var(--rock-900);
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
  border-bottom: 1px solid var(--hair);
}

.site-nav a {
  border-radius: var(--r-control);
  color: var(--ash-400);
  font-weight: 500;
  transition: color 0.16s var(--ease-out);
}
.site-nav a:hover, .site-nav a.active { color: var(--text); background: none; }

/* Dashboard nav: a rail of labels under a hairline, not a tray of pills. */
.dash-subnav {
  display: flex;
  flex-wrap: nowrap;
  gap: 2px;
  overflow-x: auto;
  scrollbar-width: none;
  padding: 0;
  margin-bottom: var(--space-5);
  background: none;
  border: 0;
  border-bottom: 1px solid var(--hair);
  border-radius: 0;
}
.dash-subnav::-webkit-scrollbar { display: none; }

.dash-subnav-link {
  flex: 0 0 auto;
  padding: 10px 14px;
  font-size: var(--fs-sm);
  font-weight: 500;
  color: var(--ash-400);
  white-space: nowrap;
  background: none;
  border: 0;
  border-radius: 0;
  transition: color 0.16s var(--ease-out);
}
.dash-subnav-link:hover { color: var(--text); background: none; }

/* [LAVA 2] active item: a molten underline sitting on the rail. */
.dash-subnav-link.dash-subnav-active {
  position: relative;
  color: var(--text);
  font-weight: 600;
  background: none;
}

.dash-subnav-link.dash-subnav-active::after {
  content: "";
  position: absolute;
  left: 10px;
  right: 10px;
  bottom: -1px;
  height: 2px;
  border-radius: 2px;
  background: var(--ember-600);
  /* No halo. A 2px rule is already the strongest signal on the bar; a glow
     around it is decoration, and it was the last unexplained one left. */
}

/* ──────────────────────────────────────────────────────────
 *  Tables: rules removed, rhythm kept
 * ────────────────────────────────────────────────────────── */
table { border-collapse: collapse; width: 100%; }

thead th {
  color: var(--ash-400);
  font-size: var(--fs-xs);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  text-align: left;
  padding: 8px 12px 8px 0;
  border-bottom: 1px solid var(--hair);
  background: none;
  backdrop-filter: none;
}

tbody td {
  padding: 11px 12px 11px 0;
  border-bottom: 1px solid var(--hair);
  font-size: var(--fs-sm);
}

tbody tr:hover { background: rgba(255, 255, 255, 0.025); }
tbody tr:last-child td { border-bottom: 0; }
td code, td .mono { font-size: 0.92em; color: var(--ember-300); }

/* ──────────────────────────────────────────────────────────
 *  Badges
 * ────────────────────────────────────────────────────────── */
.badge, .tag, .pill, .role-badge {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 2px 9px;
  border-radius: var(--r-pill);
  font-size: var(--fs-xs);
  font-weight: 600;
  border: 1px solid var(--hair-strong);
  background: none;
  color: var(--ash-400);
}

.badge-premium, .tag-premium { border-color: rgba(255, 102, 0, 0.45); color: var(--ember-300); }
.badge-ok, .status-ok { border-color: rgba(34, 197, 94, 0.4); color: #6ee7a0; }
.badge-danger { border-color: rgba(239, 83, 80, 0.45); color: #ff8a85; }

/* ──────────────────────────────────────────────────────────
 *  [LAVA 3] Premium+ and Ultimate edges
 *  Free and Premium stay plain: highlighting the middle of three tiers is
 *  the pricing-table cliche, so the weight goes on the two top plans.
 * ────────────────────────────────────────────────────────── */
.plan-premium-plus, .plan-ultimate {
  position: relative;
  padding-left: clamp(16px, 2vw, 26px);
}

.plan-premium-plus::before, .plan-ultimate::before {
  content: "";
  position: absolute;
  left: 0;
  top: 4px;
  bottom: 4px;
  width: 2px;
  border-radius: 2px;
  background: linear-gradient(180deg, var(--ember-300), var(--ember-600) 60%, transparent);
}

.plan-ultimate::before { background: linear-gradient(180deg, #fff1da, var(--ember-500) 55%, transparent); }

/* The Premium banner keeps a flat ember ground. The animated veins are gone:
   they read as decoration stuck onto a box, which is the look rev 2 removes. */
.lava-banner {
  border: 0;
  border-left: 2px solid var(--ember-600);
  border-radius: 0;
  background: linear-gradient(90deg, rgba(255, 102, 0, 0.10), transparent 62%);
  padding: clamp(16px, 2.2vw, 26px);
}
.lava-banner > canvas { display: none; }

/* ──────────────────────────────────────────────────────────
 *  Forum
 * ────────────────────────────────────────────────────────── */
.forum-post {
  background: none;
  border: 0;
  border-top: 1px solid var(--hair);
  border-radius: 0;
  padding: clamp(14px, 2vw, 22px) 0;
}
.forum-post-op { border-top-color: rgba(255, 102, 0, 0.4); }
.forum-post-deleted { opacity: 0.5; }

/* ──────────────────────────────────────────────────────────
 *  Footer
 * ────────────────────────────────────────────────────────── */
.site-footer {
  margin: 0;
  width: 100vw;
  max-width: 100vw;
  margin-inline: calc(50% - 50vw);
  padding: var(--space-5) max(calc(50vw - var(--col) / 2), 20px);
  border: 0;
  border-top: 1px solid var(--hair);
  border-radius: 0;
  /* Same ground as the page. It was a darker slab with rounded corners and
     margins, i.e. a big black rectangle sitting on the page. A hairline is
     enough to say "this is the end". */
  background: none;
  color: var(--ash-400);
  font-size: var(--fs-sm);
}
.site-footer a { color: var(--ash-400); }
.site-footer a:hover { color: var(--text); }

.small { font-size: var(--fs-sm); }
.muted, .small.muted, .muted.small { color: var(--ash-400); }

/* ──────────────────────────────────────────────────────────
 *  Focus
 * ────────────────────────────────────────────────────────── */
:where(a, button, input, select, textarea, [tabindex]):focus-visible {
  outline: 2px solid var(--ember-500);
  outline-offset: 2px;
  border-radius: var(--r-control);
}

/* ──────────────────────────────────────────────────────────
 *  Scroll reveal: removed
 *
 *  v2 does not fade content in on scroll. Three reasons, in order of weight:
 *
 *  1. It was broken. The observer asked for a threshold a tall section can
 *     never meet, so two of the three homepage sections sat at opacity:0
 *     forever and the live page was blank below the hero.
 *  2. Fading in every element on the way down is one of the clearest signs
 *     of a generated site, and it delays the content people came for.
 *  3. Keeping it meant two stylesheets negotiating opacity on every element
 *     through duelling !important rules. That is a whole class of bug for a
 *     decoration nobody asked for.
 *
 *  So: content is visible, full stop. will-change is cleared too, because
 *  the legacy sheet left a compositor layer alive on every .reveal element
 *  for an animation that no longer runs.
 * ────────────────────────────────────────────────────────── */
.reveal,
.reveal-left,
.reveal-right,
html.js-reveal .reveal,
html.js-reveal .reveal:not(.in-view) {
  opacity: 1 !important;
  transform: none !important;
  transition: none !important;
  animation: none !important;
  will-change: auto !important;
}

/* ──────────────────────────────────────────────────────────
 *  Mobile
 * ────────────────────────────────────────────────────────── */
@media (max-width: 640px) {
  :root { --band-y: 34px; }
  .stat-card, .an-stat { display: block; padding-right: 0; margin-bottom: 18px; }
  .checkbox-line:hover, .feature-toggle:hover, .dash-row:hover { box-shadow: none; }
  thead th, tbody td { padding-right: 8px; }
}

/* ──────────────────────────────────────────────────────────
 *  Reduced motion
 * ────────────────────────────────────────────────────────── */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    scroll-behavior: auto !important;
  }
  .reveal, html.js-reveal .reveal { opacity: 1 !important; transform: none !important; }
  .btn-primary::after { display: none; }
}

/* ============================================================
 *  PART 3 - the islands that rev 2 missed
 *
 *  Rev 2 flattened .card and .section-shell, but the homepage and the
 *  premium page do not use those. They use .lb-feature, .tier-card,
 *  .guide-card and friends, which kept their borders, fills and rounded
 *  corners. That is why the page still read as a raft of floating panels:
 *  the rule existed, it just never reached the markup that matters.
 *
 *  Everything below is the same decision applied to the classes that were
 *  actually on screen.
 * ============================================================ */

/* ──────────────────────────────────────────────────────────
 *  Every remaining panel class, flattened
 * ────────────────────────────────────────────────────────── */
.lb-feature,
.tier-card,
.guide-card,
.donation-card,
.premium-status-card,
.auth-card,
.stat-card,
.an-stat,
.feature-card,
.lb-mock-card,
.info-tip {
  background: none !important;
  background-color: transparent !important;
  border: 0 !important;
  border-radius: 0 !important;
  box-shadow: none !important;
  backdrop-filter: none !important;
}

/* ──────────────────────────────────────────────────────────
 *  The feature grid becomes a list of entries
 *
 *  Eight equal boxes in a 4x2 grid is the single most recognisable shape of
 *  a generated page. As columns of text separated by a hairline, the same
 *  content reads as a spec sheet: scannable, and obviously written by
 *  someone who knows the product.
 * ────────────────────────────────────────────────────────── */
.lb-feature-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 0;
  column-gap: clamp(24px, 4vw, 56px);
  margin-top: 8px;
}

.lb-feature {
  padding: 20px 0;
  border-top: 1px solid var(--hair) !important;
  display: block;
}

.lb-feature h3 {
  font-size: 1.02rem;
  font-weight: 600;
  margin: 0 0 5px;
  letter-spacing: -0.015em;
  color: var(--text);
}

.lb-feature p {
  margin: 0;
  color: var(--ash-400);
  font-size: var(--fs-sm);
  line-height: 1.55;
  max-width: 46ch;
}

/* The icon slot: the emoji are gone from the markup and custom icons are
   coming. Until they land this is a small ember rule, which marks the entry
   without pretending to be an illustration. An empty box would just look
   like a missing asset. */
.lb-feature-ic {
  width: 18px;
  height: 2px;
  border-radius: 1px;
  background: var(--ember-600);
  margin-bottom: 12px;
  font-size: 0;            /* neutralises any glyph left behind */
  line-height: 0;
}

.lb-feature-ic > * { display: none; }

/* ──────────────────────────────────────────────────────────
 *  Pricing: columns, not cards
 *
 *  The recommended tier keeps its emphasis, but through weight and a molten
 *  rule rather than a ring around a box.
 * ────────────────────────────────────────────────────────── */
.lb-plans,
.tier-grid,
.plan-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: 0;
  column-gap: clamp(20px, 3vw, 44px);
}

.tier-card {
  padding: 26px 0 !important;
  border-top: 1px solid var(--hair) !important;
  position: relative;
}

.tier-card.featured,
.tier-card.recommended,
.plan-premium-plus,
.plan-ultimate {
  border-top-color: var(--ember-600) !important;
}

/* The "RECOMMENDED" chip was a filled pill pinned to a card edge. As a
   quiet label above the tier name it says the same thing without the box. */
.tier-card .badge,
.tier-card .pill {
  position: static !important;
  transform: none !important;
  margin-bottom: 8px;
  background: none !important;
  border: 0 !important;
  padding: 0 !important;
  color: var(--ember-500) !important;
  font-size: var(--fs-xs);
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

/* ──────────────────────────────────────────────────────────
 *  Eyebrows: gone
 *
 *  A label reading "Features" directly above a heading reading "Everything
 *  a busy server needs" is a label stacked on a label. They were removed
 *  from index.html; this catches the ones rendered from the database so a
 *  stale stored page cannot put them back.
 * ────────────────────────────────────────────────────────── */
.island-eyebrow,
.lb-hero-pill,
.section-eyebrow,
.eyebrow,
.page-head > .pill,
.page-head > p.pill {
  display: none !important;
}

/* ──────────────────────────────────────────────────────────
 *  Hero
 * ────────────────────────────────────────────────────────── */
.lb-hero {
  position: relative;
  overflow: hidden;
  isolation: isolate;
}

.lb-hero-copy h1 { max-width: 16ch; }
.lb-hero-copy .lede, .lb-hero-copy p { max-width: 52ch; }

/* [LAVA] the vein canvas draws here. It is behind everything and clipped to
   the hero band, so it reads as the ground the page sits on rather than a
   decorated rectangle. */
.lb-hero > canvas[data-lava-canvas] {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  z-index: -1;
  pointer-events: none;
  opacity: 0.55;
}

/* ──────────────────────────────────────────────────────────
 *  Mock panel on the hero: keep one frame, drop the gloss
 *
 *  The Discord mock is the one place a bordered rectangle is correct: it is
 *  depicting a window. It gets a flat ground and a hairline, no gradient.
 * ────────────────────────────────────────────────────────── */
.lb-mock {
  background: var(--rock-850) !important;
  border: 1px solid var(--hair) !important;
  border-radius: 10px !important;
  box-shadow: none !important;
}

.lb-mock-card {
  border-top: 1px solid var(--hair) !important;
  border-radius: 0 !important;
  padding: 12px 0 !important;
}


/* ──────────────────────────────────────────────────────────
 *  No frosted glass anywhere
 *
 *  The legacy sheet blurs what is behind the nav dropdown, the toast and
 *  the cookie banner. Same objection as the top bar: it is the
 *  glassmorphism tell, and each blurred layer is a per-frame repaint. All
 *  four get a solid ground instead, which is also more readable.
 * ────────────────────────────────────────────────────────── */
.topbar,
.site-nav .nav-dd-menu,
.toast,
.cookie-banner,
.modal, .dialog, .popover {
  backdrop-filter: none !important;
  -webkit-backdrop-filter: none !important;
}

.site-nav .nav-dd-menu,
.toast,
.cookie-banner {
  background: var(--rock-800) !important;
  border: 1px solid var(--hair) !important;
  box-shadow: none !important;
}

/* Catch-all: no element gets a coloured halo. Glows that ARE wanted are
   drawn deliberately (the vein canvas), never bolted on as a shadow. */
.badge, .tag, .pill, .btn-primary, .btn-ghost, .btn-danger,
.stat-card, .lb-feature, .tier-card, .card, .section-shell {
  text-shadow: none !important;
}

/* The legacy sheet floats primary buttons on a 20px drop shadow. Nothing
   else on the page casts a shadow any more, so a hovering button is the
   one bit of fake depth left. Flat, like everything else. */
.btn, .btn-primary, .btn-ghost, .btn-danger {
  box-shadow: none !important;
}

/* The logo floated on a 22px drop shadow. Nothing else casts one now. */
.brand-mark, .docs-brand-mark { box-shadow: none !important; }

/* Deliberately NOT touched: .iris-btn keeps its lava-to-blue edge glow.
   That one was specified on purpose as the LavaBot x IRIS crossover mark,
   so it is a brand element rather than ambient decoration. It is the only
   coloured halo left on the site; say the word and it goes flat too. */

/* The hero announcement was a pill with class "pill", not the classes the
   earlier rule targeted, so it survived. Any label sitting directly above a
   headline is the mini-hero pattern and goes. */
.lb-hero .pill,
.lb-hero-copy > .pill,
.page-head .pill { display: none !important; }

/* ──────────────────────────────────────────────────────────
 *  Product screenshots
 *
 *  Replaces the invented dashboard mock. A screenshot IS a window, so
 *  unlike everything else on this page it legitimately gets a frame: a
 *  hairline and a small radius, nothing more. No shadow, no glow, no tilt.
 * ────────────────────────────────────────────────────────── */
.lb-shot { margin: 0; max-width: 100%; }

.lb-shot img {
  display: block;
  width: 100%;
  height: auto;
  border: 1px solid var(--hair);
  border-radius: 10px;
  background: var(--rock-850);
}

.lb-shot figcaption {
  margin-top: 10px;
  color: var(--ash-400);
  font-size: var(--fs-xs);
}

/* ──────────────────────────────────────────────────────────
 *  Full-bleed without sideways scroll
 *
 *  The band technique uses 100vw, and 100vw INCLUDES the scrollbar while
 *  the containing block does not. The difference (about 5px on a desktop
 *  with a classic scrollbar) leaks out as horizontal scroll. Clipping the
 *  root removes it without affecting sticky or fixed children the way
 *  overflow:hidden would.
 * ────────────────────────────────────────────────────────── */
html { overflow-x: clip; }

@supports not (overflow: clip) {
  html { overflow-x: hidden; }
}

/* ============================================================
 *  PART 4 - no divider lines
 *
 *  Rev 2 replaced boxes with hairlines. Boxes were the problem, but a
 *  hairline under every row is still a drawn partition: the page ends up
 *  ruled like a ledger. They all come out here.
 *
 *  THE TRADE, stated plainly: a divider does real work, it tells you where
 *  one item ends. Delete it and add nothing, and the content turns to mush.
 *  So every removal below is paid for with vertical space. That is the only
 *  thing separating items now, which is why the padding values go UP rather
 *  than staying where they were.
 *
 *  What keeps a border, and why it is not a divider:
 *    - inputs, selects, textareas, ghost buttons: an affordance. The border
 *      is what says "you can type here".
 *    - the screenshot frame: it depicts a window.
 * ============================================================ */

.card,
.section-shell,
.checkbox-line,
.feature-toggle,
.dash-row,
.lb-feature,
.tier-card,
.forum-post,
.lb-mock-card,
.site-footer,
.support-list li,
.roadmap-list li,
.changelog-entry ul li,
.feature-list li,
.dash-subnav,
.topbar,
thead th,
tbody td,
tbody tr:last-child td {
  border-top: 0 !important;
  border-bottom: 0 !important;
}

/* ── Compensation: air replaces every line removed above ── */

.card { padding: clamp(26px, 3.4vw, 44px) 0; }

/* Settings rows carry the hover tint as their only edge cue, so they need
   to be tall enough that the tint reads as a band rather than a smear. */
.checkbox-line,
.feature-toggle,
.dash-row { padding: 16px 4px; }

.lb-feature { padding: 28px 0; }
.tier-card { padding: 34px 0 !important; }
.forum-post { padding: clamp(20px, 2.6vw, 30px) 0; }

.support-list li,
.roadmap-list li,
.changelog-entry ul li,
.feature-list li { padding: 14px 0 14px 22px; }

.support-list li::before,
.roadmap-list li::before,
.changelog-entry ul li::before,
.feature-list li::before { top: 1.35em; }

/* Tables lose their rules too. Rows stay legible through height and the
   hover tint; the header separates by weight and letter-spacing, not by a
   line under it. */
thead th { padding: 6px 14px 14px 0; }
tbody td { padding: 14px 14px 14px 0; }
tbody tr:hover { background: rgba(255, 255, 255, 0.03); }

/* The dashboard rail sits on space alone. */
.dash-subnav { margin-bottom: var(--space-6); }

/* The footer is the end of the document, so it gets the largest gap on the
   page instead of a rule above it. */
.site-footer { padding-top: clamp(40px, 5vw, 72px); }

/* The top bar is the one place where a boundary is load-bearing: it is
   sticky, so content scrolls UNDER it and without an edge the two planes
   merge. It keeps a separation, but as a shadowless step in tone rather
   than a white line. */
.topbar {
  background: var(--rock-950) !important;
  box-shadow: none !important;
}
