/* Shared Forge authoring styles. Issue #100.

   GLOBAL on purpose, and opt-in on purpose. Blazor scoped CSS only ever reaches the one component it
   belongs to, so two pages that render the same chrome had to restate it — /forge/worlds and
   /forge/adventures had drifted into two byte-identical stylesheets (SHA256 1C940741…AAA5D).

   Every rule here is nested under a root class a page has to ASK for, exactly like .login-shell in
   app.css. That matters: an unscoped .empty-state would have reached /forge/debug-log and
   /forge/usage, whose own sheets override its border and background but not its text-align, and
   silently centred them. A shared sheet that pages opt into cannot do that.

   app.css is linked BEFORE the scoped bundle, so a page that disagrees with anything here can still
   override it from its own .razor.css at equal specificity. Defaults, not decrees. */

/* ── The Forge palette ────────────────────────────────────────────────────────────────────────────
   Before this, the Forge stylesheets held 778 colour literals in 339 distinct values. These 41 are
   the ones stated in three or more files — 294 of those literals — so they were shared decisions
   pretending to be local ones. #e6b85c alone appeared 42 times across 7 pages.

   Names describe the ROLE, because each of these is used for essentially one job: every use of
   --forge-gold-ink is text sitting on a gold fill, every use of --forge-border-input is an input's
   border. The 45 remaining multi-file colours and every single-page accent stay literal on purpose;
   a token nobody shares is just indirection.

   The surfaces are NUMBERED, not named, and that is a deliberate confession: --forge-surface-1
   through -6 are six near-blacks within about two percent of each other (#15120e #15130f #16130f
   #17140f #191713 #1a1712). They are almost certainly meant to be fewer. Collapsing them would
   change pixels on live pages, so this file preserves them exactly and makes the drift countable
   instead of inventing six role names that would launder it. */

:root {
    /* Accent */
    --forge-gold: #e6b85c;
    --forge-gold-bright: #f0d18d;
    --forge-gold-ink: #17130d;              /* text on a gold fill */

    /* Text, brightest to faintest */
    --forge-text: #eee8dc;
    --forge-text-input: #f1eadf;
    --forge-text-label: #cdbfaa;
    --forge-text-muted: #b8ad9b;
    --forge-text-dim: #a99c88;
    --forge-text-faint: #8f8372;
    --forge-text-eyebrow: #8e816e;

    /* Surfaces. See the note above about 1–6. */
    --forge-surface-well: #0d0b08;
    --forge-surface-1: #15120e;
    --forge-surface-2: #15130f;
    --forge-surface-3: #16130f;
    --forge-surface-4: #17140f;
    --forge-surface-5: #191713;
    --forge-surface-6: #1a1712;
    --forge-surface-input: #262119;
    --forge-surface-button: #31291e;
    --forge-surface-hover: #211d17;
    --forge-surface-selected: #292116;
    --forge-surface-chip: #302a22;
    --forge-surface-notice: #211b13;

    /* Borders */
    --forge-border-nested: #443a2c;
    --forge-border-nav: #453a2b;
    --forge-border-card: #4c4233;
    --forge-border-editor: #51442f;
    --forge-border-input: #66563e;
    --forge-border-panel: #68583d;
    --forge-border-quiet: #766247;
    --forge-border-gold: #80663d;

    /* Success */
    --forge-success: #9bd391;
    --forge-success-border: #5f9d73;
    --forge-success-border-alt: #507c48;
    --forge-success-surface: #172019;
    --forge-success-badge: #17301d;

    /* Danger */
    --forge-danger: #ffb1a0;
    --forge-danger-alt: #ff9c87;
    --forge-danger-border: #8f4f43;
    --forge-danger-border-alt: #c55;
    --forge-danger-surface: #281717;
}

/* ── Shared by every Forge page ───────────────────────────────────────────────────────────────────
   .section-heading is stated identically by 7 of the 9 pages that use it: Admin, Adventures,
   Creatures, Settings, Worlds and both library pages. Automation (centred, wrapping, margined) and
   Library (gap .75rem) genuinely disagree and keep their own rules — both already set every property
   this one does, so their scoped sheets simply win on source order and nothing leaks into them. */

.forge-content .section-heading { display: flex; align-items: flex-start; justify-content: space-between; gap: 1rem; }

/* ── The primary action (#552, unblocking #124) ───────────────────────────────────────────────────
   ⛔ #100 skipped .primary and #124 recorded why: "promoting it would make the shared rule
   out-specify Library's weight, so preserving Library's look needs a NEW !important". THAT PREMISE IS
   FALSE, and it was measured against the built bundle rather than reasoned about:

     ForgeLibrary.razor.css's `.primary` compiles to `.primary[b-frxd7e2l1a]` — read out of
     obj/…/scopedcss/bundle/DungeonMaster.Web.styles.css, not assumed. Blazor's scope attribute makes
     it (0,2,0), which TIES with `.forge-content .primary` rather than losing to it, and App.razor
     links forge.css BEFORE the scoped bundle (pinned by TheSharedSheetIsLinkedBeforeTheScopedBundle),
     so the later sheet takes the tie. Library keeps its font-weight:800 and its three !importants
     with nothing added. Worlds (.world-editor-actions .primary) and Creatures
     (.character-editor-actions .primary) are (0,3,0) and were never in danger.

   So this is the majority token, stated once, with no !important: Worlds and Creatures are
   byte-identical and that pair IS the majority (#124's own reading). Library is the outlier and keeps
   its own rule by the cascade, exactly as .section-heading above already works.

   ⚠️ What this DOES and does not reach, counted button by button across the nine pages that render
   class="primary" with no rule of their own — 17 buttons, and the issue's two named examples are both
   wrong about themselves:
     ✔ FIXED (8, browser-default grey today, nothing reaches them at all): ForgeAdmin ×5,
       ForgeAssets (.detail-facts — outside every .character-editor-card, which close at 73/137/226),
       ForgeDebugLog (.filters), ForgeMapStudio (.ai-model — .ai-helper-button is a sibling class).
     ✔ ALREADY GOLD, unchanged (7): both library pages and ForgeArena's "Begin" via
       `.forge-library .library-header button` below; ForgeSettings' "Save settings securely" ×2 via
       its own `.settings-header button, .save-bar button`. Every one of those is (0,2,1) or scoped,
       so this rule loses to them and moves no pixel.
     ✘ NOT reached (2): ForgeAdventures' two .map-import buttons, which its own
       `.forge-editor-card button` paints with --forge-surface-button. Deliberately left losing —
       out-shouting a page that has stated an opinion is the !important trade #124 refused, and
       whether that confirm button should be gold is a design call. Filed separately. */

.forge-content .primary { color: var(--forge-gold-ink); background: var(--forge-gold); border-color: var(--forge-gold); font-weight: 700; }

/* ── The editor card shell ────────────────────────────────────────────────────────────────────────
   Issue #191. ForgeAssets.razor.css restated ForgeCreatures.razor.css's card and field rules
   BYTE-FOR-BYTE, with a comment at the top saying so, because scoped CSS never crosses components.

   .character-editor-* appears in exactly two markup files — ForgeAssets.razor and ForgeCreatures.razor
   — so .forge-content (the ForgeLayout <main>) is already tighter than the class name itself. It is
   still named as the root because the alternative, an unscoped .character-editor-card, would be one
   rename away from reaching /play, which uses .character-* names of its own.

   Only rules IDENTICAL in both sheets moved. The selectors each page adds to those same rules stay
   put: ForgeCreatures keeps .nested-heading, .character-row label, .character-editor-card h3/h4 and
   the card's textarea; ForgeAssets keeps :disabled, `code`, and .character-editor-header h1/p.

   .row-actions is deliberately NOT here even though Assets and Creatures agree on it: ForgeAutomation
   sets its own .row-actions without flex-wrap, and a shared rule would leak wrapping into it. #295.

   align-items:start is preserved verbatim rather than normalised to flex-start — identical in a flex
   container, but this is a dedup and nothing here gets to move a pixel. */

.forge-content .character-editor-header { display: flex; align-items: start; justify-content: space-between; gap: 1rem; }
.forge-content .character-editor-actions { display: flex; flex-wrap: wrap; gap: .6rem; }

.forge-content .character-editor-card { display: grid; gap: 1rem; margin: 1rem 0; padding: 1.1rem; border: 1px solid var(--forge-border-editor); border-radius: .4rem; background: var(--forge-surface-6); }
.forge-content .character-editor-card h2 { margin: 0; color: var(--forge-gold); }
.forge-content .character-editor-card p { margin: 0; }
.forge-content .character-editor-card label { display: grid; gap: .3rem; color: var(--forge-text-label); }

.forge-content .character-editor-card input,
.forge-content .character-editor-card select { min-width: 0; color: var(--forge-text-input); background: var(--forge-surface-input); border: 1px solid var(--forge-border-input); padding: .5rem; }

.forge-content .character-editor-card button,
.forge-content .character-editor-actions button { width: fit-content; color: var(--forge-text); background: var(--forge-surface-button); border: 1px solid var(--forge-border-quiet); padding: .5rem .75rem; cursor: pointer; }

@media (max-width: 700px) {
    .forge-content .character-editor-header { display: grid; }
}

/* ── Editor field, status and validation primitives ───────────────────────────────────────────────
   These names are shared more widely — .field-grid.four across Assets, Creatures and Worlds;
   .editor-status across those three and ForgeLibrary; .validation-card across Creatures, Library and
   Worlds — and in every case the declarations below were stated identically by all of them.

   What did NOT agree stays scoped, on purpose:
   · the .editor-status STICKINESS. All four pages give it a different sticky offset and z-index, and
     Library also zeroes its margin. Its tail is shared — see the next block.
   · every .field-grid.four MEDIA QUERY. Assets and Creatures fold at 1050px then 700px; Worlds folds
     once at 900px. A shared breakpoint would newly reflow one of them, which is a visual change.
     The page sheets keep their own, and win the tie on source order.
   · .field-grid itself (four pages, four different gaps) and .eyebrow (five ways, and used far
     outside the Forge). Those are #124.

   Specificity note, since these rules LOST an attribute selector on the way here: forge.css is linked
   before the scoped bundle, so where a page states the same selector at the same weight the page
   still wins. .forge-content .field-grid.four is (0,3,0), exactly what .field-grid.four[b-xxxxx] was,
   so ForgeWorlds' 900px override still beats it. */

.forge-content .field-grid.four { display: grid; grid-template-columns: repeat(4, minmax(10rem, 1fr)); gap: .75rem; }

/* ── The .editor-status tail (#313) ───────────────────────────────────────────────────────────────
   #295 recorded .editor-status as "four different sticky offsets", which is true of the HEAD of each
   rule and not of its TAIL: padding, border and background were byte-identical in all four page
   sheets, and Creatures and Worlds were identical outright. So the promotable unit is the tail. Each
   page keeps only what actually differs — its position/top/z-index, and Library's margin: 0 — and
   ForgeAssets, which was never sticky, keeps nothing and loses its rule entirely.

   THE ENUMERATION, so the next pass does not have to redo it. Every element in the app carrying the
   class `editor-status` is in one of exactly four markup files, all four of them @layout ForgeLayout
   and therefore already inside .forge-content:
     ForgeAssets.razor    ×3 (all literal "editor-status error" / "editor-status success")
     ForgeCreatures.razor ×2 (the page status line, and one per validation panel)
     ForgeWorlds.razor    ×1
     ForgeLibrary.razor   ×2 (the page status line, and one per validation panel)
   Nothing else in the app states or renders the name, so nothing NEWLY inherits the three
   declarations below. Note that /forge/creatures is ForgeLibrary; ForgeCreatures is the legacy page
   at /forge/creatures/legacy.

   ORDER MATTERS HERE, in two directions:
   · `border: 1px solid` deliberately names no colour, so it resolves to currentColor, and .error /
     .success below set both the colour and the border-colour. Those weigh (0,3,0) against this
     rule's (0,2,0), so they win on specificity and would do so at any position — but the tail is
     stated ABOVE them anyway, because relying on a specificity margin that a future edit could erase
     is how this file's 900px fold nearly went wrong.
   · the pages keep winning their own heads because a scoped .editor-status[b-xxxxx] also weighs
     (0,2,0) and the scoped bundle is linked AFTER this sheet. They set different properties in any
     case, so there is nothing to tie over. */

.forge-content .editor-status { padding: .75rem 1rem; border: 1px solid; background: var(--forge-surface-3); }

.forge-content .editor-status.error { color: var(--forge-danger-alt); border-color: var(--forge-danger-border); }
.forge-content .editor-status.success { color: var(--forge-success); border-color: var(--forge-success-border-alt); }

.forge-content .draft-state { color: var(--forge-text-dim); }
.forge-content .validation-card code { color: var(--forge-gold); }

/* ── The world / adventure workspace ──────────────────────────────────────────────────────────────
   /forge/worlds and /forge/adventures render the same shell. ForgeAdventures.razor.css used to say
   so in a comment — "the studio wears the world workspace's clothes on purpose" — and then restate
   every rule. These are the ten that were byte-identical.

   Scoped to .forge-content rather than an opt-in wrapper because these class names are used by those
   two pages and nowhere else, so the page scope IS the component scope. The library block below
   needs the opt-in treatment precisely because ITS names (.empty-state, .card-actions) are shared.

   The fourteen rules that DIFFER stay in the page sheets on purpose. Adventures is a refinement of
   Worlds — rounded corners, box-sizing, font:inherit, full-width controls — so unifying them means
   deciding whether the world editor adopts the studio's look. That is a design call, not a dedup.

   .world-save-state span is safe to share despite the pages' own .world-save-state .valid rules:
   scoped CSS adds an attribute selector, so those weigh (0,3,0) against this sheet's (0,2,1) and keep
   winning. The validation colours still beat the default they sit on. */

.forge-content .workspace-loading { padding: 3rem 1rem; text-align: center; }
.forge-content .world-workspace { display: grid; grid-template-columns: 15rem minmax(0, 1fr); align-items: start; gap: 1rem; }
.forge-content .world-section-nav { position: sticky; top: 7.5rem; display: grid; gap: .3rem; padding: .75rem; border: 1px solid var(--forge-border-nav); border-radius: .4rem; background: var(--forge-surface-4); }
.forge-content .world-section-nav a { display: grid; gap: .15rem; padding: .55rem .65rem; color: #d8c9b0; border-left: 3px solid transparent; text-decoration: none; }
.forge-content .world-section-nav a:hover { background: var(--forge-surface-hover); }
.forge-content .world-section-nav a.active { color: var(--forge-gold-bright); border-left-color: var(--forge-gold); background: var(--forge-surface-selected); }
.forge-content .world-section-nav small { color: var(--forge-text-faint); font-size: .68rem; line-height: 1.3; }
.forge-content .world-save-state span { color: var(--forge-text-dim); font-size: .76rem; }

/* The narrow fold for the two rules above, promoted with them (#295). It has to live HERE, after the
   bases it overrides, and it could only follow them once they were in this file — a media query adds
   no specificity, so this weighs (0,2,0) exactly as the base does and wins on source order alone.
   That is why the other identical @media pairs the audit found were left in their page sheets: their
   bases are still scoped, this sheet loads BEFORE the scoped bundle, and an override moved up here
   would have started losing the tie to the very base it exists to override — silently, at one
   viewport width, which is the worst way to find out. */
@media (max-width: 900px) {
    .forge-content .world-workspace { grid-template-columns: 1fr; }
    .forge-content .world-section-nav { position: static; grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

.forge-content .forge-editor-card h2,
.forge-content .forge-editor-card h3 { margin: 0; color: var(--forge-gold); }

/* ── Two one-liners off the report and admin pages (#295) ─────────────────────────────────────────
   .table-scroll is the wrapper ForgeAdmin and ForgeSettings both put round a wide table; .settings-link
   is the "go to settings" link in ForgeDebugLog's and ForgeUsage's headers. Each was stated, character
   for character, in exactly the two sheets whose pages use the name, and nothing else in the app
   declares either — so there is no rule left for these to tie with and nothing new can inherit them.
   They sit at .forge-content scope because that is the layout's <main>, which every Forge page is
   already inside; no page has to opt in and no page outside the Forge can be reached. */

.forge-content .table-scroll { overflow: auto; }
.forge-content .settings-link { white-space: nowrap; }

/* ── The library chrome: a searchable grid of authored packs ──────────────────────────────────────
   Used by ForgeWorldLibrary (worlds) and ForgeAdventureLibrary (adventures). The card classes were
   called .world-card etc. in both copies, which was a lie on the adventure page. They are .pack-card
   now — both pages list content PACKS, which is what the adventure page's own "adventure pack(s)"
   counter already called them. Not .library-card: ForgeLibrary already uses that name for a form
   panel, and renaming one collision into another would have been worse than leaving it. */

.forge-library .library-header,
.forge-library .pack-card-heading,
.forge-library .pack-card-footer,
.forge-library .library-toolbar { display: flex; align-items: flex-start; justify-content: space-between; gap: 1rem; }

.forge-library .library-header { margin-bottom: 1.25rem; }

.forge-library .library-header h1,
.forge-library .create-panel h2,
.forge-library .pack-card h2,
.forge-library .empty-state h2 { margin: .15rem 0; color: var(--forge-gold-bright); }

.forge-library .library-header p,
.forge-library .create-panel p,
.forge-library .pack-card p,
.forge-library .empty-state p { color: var(--forge-text-muted); }

.forge-library .library-header button,
.forge-library .create-panel button { width: fit-content; color: var(--forge-gold-ink); background: var(--forge-gold); border: 1px solid var(--forge-gold); padding: .6rem .85rem; font-weight: 700; cursor: pointer; }

.forge-library .create-panel button.quiet { color: #d8c49f; background: transparent; border-color: var(--forge-border-quiet); }

/* ── Creating a new pack ── */

.forge-library .create-panel { display: grid; gap: 1rem; margin: 1rem 0; padding: 1rem; border: 1px solid var(--forge-border-panel); background: var(--forge-surface-5); }
.forge-library .create-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: .8rem; }

.forge-library .create-grid label,
.forge-library .library-toolbar label { display: grid; gap: .3rem; color: var(--forge-text-label); }

.forge-library .create-grid input,
.forge-library .library-toolbar input { min-width: 0; box-sizing: border-box; width: 100%; padding: .55rem; color: var(--forge-text-input); background: var(--forge-surface-input); border: 1px solid var(--forge-border-input); }

/* ── Status line and search toolbar ── */

.forge-library .library-status { padding: .75rem 1rem; border-left: 3px solid var(--forge-success-border); background: var(--forge-success-surface); }
.forge-library .library-status.error { border-color: var(--forge-danger-border-alt); background: var(--forge-danger-surface); }
.forge-library .library-toolbar { align-items: end; margin: 1.25rem 0; }
.forge-library .library-toolbar label { width: min(34rem, 100%); }
.forge-library .library-toolbar span { color: #a99d89; }
/* The toolbar's only other label is the search field, which is a stacked grid 34rem wide with a
   full-width input. A checkbox has to opt out of all three, or it stretches across a third of the
   toolbar.
   ⚠️ This used to end "— the same trap app.css's bare `input { width: 70% }` sets on every page". That
   rule is GONE: #126 deleted the POC tabletop stylesheet, and app.css now carries a long comment where
   it used to be. The trap here is real and is entirely local — `.library-toolbar label` sets
   display:grid and the input below it sets width:100% — so the opt-out is still needed for its own
   reasons, and the citation was pointing at a rule that no longer exists. */
.forge-library .library-toolbar label.version-toggle { display: flex; align-items: center; gap: .45rem; width: auto; white-space: nowrap; color: var(--forge-text-muted); cursor: pointer; }
.forge-library .library-toolbar label.version-toggle input { width: auto; padding: 0; }

/* ── The card grid ── */

.forge-library .pack-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(20rem, 1fr)); gap: 1rem; }
.forge-library .pack-card { display: grid; gap: .8rem; padding: 1rem; border: 1px solid var(--forge-border-card); border-radius: .45rem; background: var(--forge-surface-5); }
.forge-library .pack-card h2 { font-size: 1.2rem; }
.forge-library .pack-id { margin: 0; font: 700 .72rem/1.2 ui-monospace, monospace; letter-spacing: .04em; }
.forge-library .pack-state { white-space: nowrap; padding: .2rem .5rem; border-radius: 999px; font-size: .75rem; }
.forge-library .pack-state.working { color: #f0cc80; background: #3b2d13; }
.forge-library .pack-state.published { color: var(--forge-success); background: var(--forge-success-badge); }
/* Superseded, and shown only through the toggle. Deliberately the quietest badge on the card: it is
   history, and it must not compete with the version somebody is meant to be working on. */
.forge-library .pack-state.older { color: #a99d89; background: var(--forge-surface-5); }
.forge-library .pack-ruleset { margin: 0; }
/* ⛔ #1241. A working copy branched from a version something newer has since replaced. A SENTENCE, not another
   badge: two cards reading "fenreach · 1.1.0" and "fenreach · 1.4.0" say nothing about which is the old world,
   and Dave's pair differed by 2 regions and 94 places. Danger colours because publishing it would lose them. */
.forge-library .pack-superseded { margin: 0; padding: .5rem .65rem; border-left: 3px solid var(--forge-danger-border); background: var(--forge-danger-surface); color: var(--forge-danger); font-size: .8rem; }
.forge-library .card-actions button.danger { color: var(--forge-danger); border-color: var(--forge-danger-border); }
/* ⛔ #1241. The two library pages have no scoped sheet of their own, so `.muted` — which every other Forge
   page declares in its own — had nowhere to resolve from and the discard dialog's explanatory lines drew as
   ordinary body text. Same declaration the adventure and world workspaces use, so the shade does not differ
   between a dialog opened from the library and the same words on the page behind it. */
.forge-library .muted { color: var(--forge-text-faint); font-size: .85rem; }
/* Inside the discard dialog: the case where no published version is left behind afterwards. */
.forge-library .discard-warning { margin: 0; padding: .6rem .7rem; border-left: 3px solid var(--forge-danger-border-alt); background: var(--forge-danger-surface); color: var(--forge-danger); }

/* A world declares four counts and an adventure three; the fourth column stays empty by design. */
.forge-library .pack-card dl { display: grid; grid-template-columns: repeat(4, 1fr); gap: .5rem; margin: 0; }
.forge-library .pack-card dl div { padding: .55rem; background: #12100d; }
.forge-library .pack-card dt { color: #a99d89; font-size: .72rem; }
.forge-library .pack-card dd { margin: .15rem 0 0; color: var(--forge-gold-bright); font-size: 1.1rem; }
.forge-library .pack-card-footer { align-items: center; border-top: 1px solid #332f28; padding-top: .75rem; color: #a99d89; font-size: .8rem; }
.forge-library .pack-open { color: var(--forge-gold); font-weight: 700; text-decoration: none; }

.forge-library .empty-state { padding: 2rem; border: 1px dashed #574a37; text-align: center; background: var(--forge-surface-4); }

/* ── Row and header action clusters ── */

.forge-library .library-actions,
.forge-library .card-actions { display: flex; align-items: center; gap: .6rem; }

.forge-library .library-actions a { color: #d8c49f; text-decoration: none; }
.forge-library .card-actions button { padding: .35rem .55rem; color: #d8c49f; background: transparent; border: 1px solid var(--forge-border-input); cursor: pointer; }

@media (max-width: 700px) {
    .forge-library .library-header,
    .forge-library .section-heading,
    .forge-library .pack-card-footer,
    .forge-library .library-toolbar { display: grid; }

    .forge-library .create-grid { grid-template-columns: 1fr; }
    .forge-library .pack-card dl { grid-template-columns: repeat(2, 1fr); }
}


/* ------------------------------------------------------------------------------------------------
   The RAIL: the side panel every Forge studio builds its controls out of.

   ⛔⛔ GLOBAL, and it used to be scoped to ForgeWorldStudio. Scoped CSS is per COMPONENT, so the Game
   Library wrote the same markup — `rail-field`, `rail-hint`, `rail-list`, `rail-note`, `rail-pick` —
   against rules it could not reach, and five class names drew nothing while nothing errored (#122,
   #762). The names were never the world studio's; they are the vocabulary a rail is written in.

   ⚠️ Promoted whole rather than the five the Game Library happened to need. Splitting a design
   language across a scoped sheet and a global one is the drift that caused this, one page later.

   ⛔⛔ **SCOPED TO `.forge-content`, and the note here used to say the blast radius was "accepted
   knowingly".** It was not anybody's to accept: `EveryForgeRuleIsScopedToAForgeRoot` forbids exactly this
   and has been RED on this branch since the promotion, because forge.css is page-wide and an unscoped
   family reaches /play and the account pages, which never asked for Forge chrome. The guard's own
   reasoning is the answer to the note's: the damage lands somewhere else entirely, so "nothing else
   declares this family TODAY" is the argument it exists to refuse.

   ⭐ One root is enough and nothing is lost by it. Both pages that write this vocabulary — the world
   studio and the Game Library — are `@layout ForgeLayout`, whose `<main>` IS `.forge-content`, so the
   promotion still does what #762 asked: one home, reachable from either page.

   ⚠️ Play's `.rail-icon` and LevelUpPanel's `.rail-step` are a different family and were never in
   here; nothing outside the Forge writes these names.
   ------------------------------------------------------------------------------------------------ */
.forge-content .rail-block {
    background: #161d2b;
    border: 1px solid #2a3346;
    border-radius: .5rem;
    padding: .5rem .6rem .6rem;
}

.forge-content .rail-block h3 {
    margin: 0 0 .4rem;
    font-size: .74rem;
    letter-spacing: .06em;
    text-transform: uppercase;
    opacity: .75;
}

.forge-content .rail-hint {
    margin: .45rem 0 0;
    font-size: .7rem;
    line-height: 1.35;
    opacity: .7;
}

.forge-content .rail-field {
    display: flex;
    flex-direction: column;
    gap: .18rem;
    font-size: .72rem;
    opacity: .9;
    margin-top: .4rem;
}

.forge-content .rail-field input,
.forge-content .rail-field select {
    width: 100%;
    padding: .25rem .35rem;
    font-size: .78rem;
    border-radius: .3rem;
    border: 1px solid #2f3a4f;
    background: #101724;
    color: inherit;
}

.forge-content .rail-pair {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: .4rem;
}

.forge-content .rail-check {
    display: flex;
    align-items: center;
    gap: .35rem;
    font-size: .75rem;
    margin-top: .3rem;
}

.forge-content .rail-actions {
    display: flex;
    gap: .3rem;
    margin-top: .45rem;
    flex-wrap: wrap;
}

.forge-content .rail-actions input[type="text"] {
    flex: 1 1 6rem;
    min-width: 0;
    padding: .25rem .35rem;
    border-radius: .3rem;
    border: 1px solid #2f3a4f;
    background: #101724;
    color: inherit;
}

/* The tag list is a scrolling box rather than a growing one: ten tags today and more later, and a rail
   that pushes the movement class off the bottom every time the vocabulary grows is a rail that gets
   worse on its own. */
.forge-content .rail-tags {
    margin: .5rem 0 0;
    border: 1px solid #2a3346;
    border-radius: .35rem;
    padding: .3rem .4rem .4rem;
    max-height: 9rem;
    overflow-y: auto;
}

.forge-content .rail-tags legend {
    font-size: .68rem;
    text-transform: uppercase;
    letter-spacing: .05em;
    opacity: .7;
}

.forge-content .rail-list {
    list-style: none;
    margin: .4rem 0 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: .18rem;
}

.forge-content .rail-list li {
    display: flex;
    align-items: stretch;
    gap: .2rem;
    border-radius: .3rem;
}

.forge-content .rail-list li.active { background: #24344a; }

.forge-content .rail-pick {
    flex: 1 1 auto;
    min-width: 0;
    text-align: left;
    padding: .25rem .35rem;
    font-size: .76rem;
    border: none;
    background: none;
    color: inherit;
    cursor: pointer;
    display: flex;
    justify-content: space-between;
    gap: .4rem;
}

.forge-content .rail-pick span {
    opacity: .6;
    font-size: .68rem;
    white-space: nowrap;
}

.forge-content .rail-pick:hover { background: #1f293a; border-radius: .3rem; }

/* A diagnostic reads as a sentence, not as a row of controls: it is the only thing in these rails that
   is prose, and it has to wrap rather than be cut off at the width of a button. */
.forge-content .rail-note {
    display: block;
    padding: .22rem .35rem;
    font-size: .72rem;
    line-height: 1.35;
    white-space: normal;
}

.forge-content .rail-list li.warn { border-left: 2px solid #c0a03f; }
.forge-content .rail-list li.bad { border-left: 2px solid #e08b7f; }

.forge-content .rail-small {
    border: none;
    background: none;
    color: inherit;
    opacity: .6;
    cursor: pointer;
    padding: 0 .3rem;
}

.forge-content .rail-small:hover { opacity: 1; }

/* The fine-tuning dials (#456 group A, extended). One row per knob: name and current value on the
   first line, the slider under it — a rail this narrow has no room for a label beside a track. */
.forge-content .rail-dials {
    margin-top: .45rem;
    font-size: .72rem;
}

.forge-content .rail-dials summary {
    cursor: pointer;
    opacity: .8;
    padding: .15rem 0;
}

.forge-content .rail-dial {
    display: flex;
    flex-direction: column;
    gap: .1rem;
    margin-top: .3rem;
}

.forge-content .rail-dial span {
    display: flex;
    justify-content: space-between;
    gap: .4rem;
    opacity: .9;
}

/* ⚠️ The value, in the editor's own chrome rather than the map's: it reports what a control is set to,
   which is a fact about the tool and not about the country. */
.forge-content .rail-dial em {
    font-style: normal;
    opacity: .65;
    font-variant-numeric: tabular-nums;
}

.forge-content .rail-dial input[type=range] {
    width: 100%;
    padding: 0;
    accent-color: #7fe0ff;
}

/* Which shape keeps the ground where two meet (#477). */
.forge-content .rail-overlaps {
    margin-top: .5rem;
    border-top: 1px solid #2a3446;
    padding-top: .35rem;
}

.forge-content .rail-overlaps h4 {
    margin: 0 0 .25rem;
    font-size: .7rem;
    letter-spacing: .05em;
    text-transform: uppercase;
    opacity: .7;
}

.forge-content .rail-overlap {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: .4rem;
    font-size: .72rem;
    margin-top: .25rem;
}

.forge-content .rail-ab {
    display: flex;
    gap: .15rem;
}

.forge-content .rail-ab button {
    font-size: .68rem;
    padding: .12rem .4rem;
    border: 1px solid #2f3a4f;
    background: #101724;
    color: inherit;
    border-radius: .25rem;
    cursor: pointer;
}

/* ⚠️ The chosen side is stated by BOTH colour and weight: a pair of buttons distinguished only by hue
   says nothing to a reader who cannot separate them. */
.forge-content .rail-ab button.picked {
    background: #1d3a52;
    border-color: #7fe0ff;
    font-weight: 600;
}
