/* ============================================================================
   Manual — V0-faithful port of app/manual/page.tsx.

   Structure: glass panel landing with a 2×2 grid of four category cards.
   Each card carries its own accent color via the --accent custom property
   (set inline on the element from PHP), so this stylesheet stays generic
   and the page-level data drives the visual differentiation.

   Phasing: this file currently covers Phase 1 (panel + cards). Modal +
   tab content styles will land in Phases 2-5 below this block.
   ============================================================================ */

/* ─── Page shell ─────────────────────────────────────────────────────────── */
/*
 * Top padding is intentionally 0 — the shell's <main> already provides
 * the standard ~28-38px space below the navbar (matches halloffame's
 * reference baseline). Page-level padding adds only horizontal + bottom.
 */
.manual-page {
    position: relative;
    z-index: 10;
    width: 100%;
    padding: 0 1rem 5rem;
}
@media (min-width: 768px) {
    .manual-page { padding: 0 1.5rem 5rem; }
}

.manual-inner {
    max-width: 64rem;       /* V0 max-w-5xl */
    margin: 0 auto;
    width: 100%;
}

/*
 * Wide desktop: spend WIDTH instead of height.
 *
 * The hub is a four-item menu; on a 1080p screen the 2x2 grid pushed half
 * of it and the entire footer below the fold while ~1000px of viewport
 * width sat empty. One row of four inside a wider panel removes ~290px of
 * document height without making a single element smaller.
 *
 * 1180px is the width at which four cards still clear ~250px each after the
 * panel padding and gaps.
 */
@media (min-width: 1180px) {
    .manual-inner { max-width: 76rem; }
    /* <main> already pads the page bottom by --space-12; the extra 5rem here
       was 115px of dead space stacked above the footer. */
    .manual-page  { padding-bottom: 0; }
    /*
     * 2026-08-22: the footer grew 13px when every footer link was given a real
     * hit area, which pushed this page 4px past the fold it was built to fit.
     * <main>'s own bottom pad is --space-12 (48px) and there is a further 32px
     * of air between the panel and the footer, so 16px comes off the pad
     * rather than out of the composition. Measured after: 853px against 865.
     *
     * This is scoped to the page, not to <main> globally - every other page
     * scrolls anyway and has no reason to lose the space.
     */
    .site-main:has(.manual-page) { padding-bottom: 2rem; }
}

/* ─── Glass panel ────────────────────────────────────────────────────────── */
.manual-panel {
    position: relative;
    border-radius: 1rem;
    overflow: hidden;
    background: linear-gradient(160deg, rgba(22,16,10,0.82) 0%, rgba(12,9,6,0.88) 100%);
    border: 1px solid rgba(212, 175, 55, 0.20);
    box-shadow:
        0 0 60px rgba(0, 0, 0, 0.5),
        inset 0 1px 0 rgba(212, 175, 55, 0.10);
    opacity: 0;
    transform: translateY(16px);
    animation: manualPanelIn 0.5s cubic-bezier(0.22, 1, 0.36, 1) forwards;
}
@keyframes manualPanelIn {
    to { opacity: 1; transform: translateY(0); }
}

.manual-panel-shimmer {
    position: absolute;
    inset-inline: 0;
    height: 2px;
    pointer-events: none;
}
.manual-panel-shimmer.top {
    top: 0;
    background: linear-gradient(90deg,
        transparent 0%,
        #D4AF37 20%,
        #FFF8DC 50%,
        #D4AF37 80%,
        transparent 100%);
    box-shadow: 0 0 24px rgba(212, 175, 55, 0.7);
    border-top-right-radius: 1rem;
    border-top-left-radius: 1rem;
}
.manual-panel-shimmer.bottom {
    bottom: 0;
    height: 1px;
    background: linear-gradient(90deg,
        transparent,
        rgba(212, 175, 55, 0.25) 30%,
        rgba(212, 175, 55, 0.40) 50%,
        rgba(212, 175, 55, 0.25) 70%,
        transparent);
    border-bottom-right-radius: 1rem;
    border-bottom-left-radius: 1rem;
}

/* ════════════════════════════════════════════════════════════════════════════
   PANEL EDGE — etched rim + accent bloom
   ──────────────────────────────────────────────────────────────────────────
   Replaces four L-shaped corner brackets that sat 1rem inside each corner. They
   were decoration bolted onto the frame rather than the frame itself: identical
   on every tab, floating at an arbitrary inset, and reading as generic fantasy-UI
   furniture. Two effects take their place, and both belong to the edge itself:

     RIM   - a one-pixel hairline running the whole border, brightest at the top
             left and fading to nothing at the bottom right, as though lit from
             above. Gives the panel depth with no ornament at all.
     BLOOM - a soft wash of light spilling down from the top edge, tinted by
             `--panel-accent`, which Alpine sets from whatever you are looking at
             (the selected tribe's colour, the open guide's colour, gold
             otherwise). The frame reacts to the content instead of ignoring it.

   Both are pseudo-elements on the panel, both pointer-events:none, so neither
   can intercept a click or affect layout.
   ════════════════════════════════════════════════════════════════════════════ */

/*
 * ⚠ Both panels MUST declare this. `color-mix(in srgb, var(--panel-accent) …)`
 * is invalid at computed-value time when the variable is unset, which throws away
 * the whole `background` declaration - the rim silently rendered as nothing on the
 * landing panel while the modal, which did have the variable, looked correct.
 */
.manual-panel,
.manual-modal-panel {
    --panel-accent: #D4AF37;
}

/* RIM — gradient border via the two-layer mask trick, so a single element can
   carry a gradient on a 1px edge that follows the panel's border-radius. */
.manual-panel::after,
.manual-modal-panel::after {
    content: '';
    position: absolute;
    inset: 0;
    border-radius: inherit;
    padding: 1px;
    pointer-events: none;
    z-index: 3;
    background: linear-gradient(145deg,
        rgba(255, 244, 214, 0.55) 0%,
        color-mix(in srgb, var(--panel-accent) 30%, transparent) 18%,
        rgba(212, 175, 55, 0.10) 46%,
        rgba(255, 255, 255, 0.03) 72%,
        rgba(255, 255, 255, 0.06) 100%);
    -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
            mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
    -webkit-mask-composite: xor;
            mask-composite: exclude;
    transition: background 0.45s ease;
}

/* BLOOM — sits behind the content, above the panel background. */
.manual-panel::before,
.manual-modal-panel::before {
    content: '';
    position: absolute;
    inset-inline: 0;
    top: 0;
    height: 14rem;
    border-radius: inherit;
    pointer-events: none;
    z-index: 0;
    background:
        radial-gradient(115% 100% at 50% -12%,
            color-mix(in srgb, var(--panel-accent) 20%, transparent) 0%,
            color-mix(in srgb, var(--panel-accent) 7%, transparent) 38%,
            transparent 72%);
    transition: background 0.45s ease;
}

/* The bloom is z-index 0, so everything the reader touches is lifted above it. */
.manual-modal-content,
.manual-panel-body { position: relative; z-index: 1; }
/*
 * The header stacks ABOVE the body, not level with it.
 *
 * All three used to share z-index: 1. Equal z-index falls back to DOM order,
 * so .manual-modal-content - the later sibling - painted over the header, and
 * the header's "i" tooltip (which opens downward into the body) rendered
 * BEHIND the tribe cards: the artwork sat on top of the words.
 *
 * Raising the tip itself cannot fix this. z-index: 1 on the header makes the
 * header a stacking context, so the tip's z-index: 50 only ever competed with
 * the header's own children. The container is the thing that has to move.
 */
.manual-modal-header { position: relative; z-index: 5; }

@media (prefers-reduced-motion: reduce) {
    .manual-panel::before, .manual-panel::after,
    .manual-modal-panel::before, .manual-modal-panel::after { transition: none; }
}

.manual-panel-body {
    padding: 1.75rem 1.5rem 2rem;
}
@media (min-width: 768px) {
    .manual-panel-body { padding: 1.75rem 2.5rem 2rem; }
}
@media (min-width: 1180px) {
    .manual-panel-body { padding: 1.5rem 2.25rem 1.75rem; }
}

/* ─── Page header (Knowledge Base pill + GAME MANUAL title) ─────────────── */
/*
 * Children (icon → eyebrow pill → title block → subtitle → divider) are all
 * inline-level by default (inline-flex / inline-block), so on a wide screen
 * they would lay out on the same baseline. Forcing flex-column here stacks
 * them vertically and lets each retain its own intrinsic width via the
 * align-items: center centering rule.
 */
.manual-header {
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
    margin-bottom: 2.5rem;
    position: relative;
}
@media (min-width: 1180px) {
    .manual-header { margin-bottom: 1.75rem; }
}

.manual-header-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    margin-bottom: 0.75rem;
    color: #D4AF37;
    filter: drop-shadow(0 0 8px rgba(212, 175, 55, 0.5));
    opacity: 0;
    animation: manualFadeIn 0.45s ease 0.1s forwards;
}

.manual-eyebrow {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.375rem 1rem;
    border-radius: 9999px;
    margin-bottom: 1rem;
    background: linear-gradient(90deg,
        rgba(212, 175, 55, 0) 0%,
        rgba(212, 175, 55, 0.12) 30%,
        rgba(212, 175, 55, 0.15) 50%,
        rgba(212, 175, 55, 0.12) 70%,
        rgba(212, 175, 55, 0) 100%);
    border: 1px solid rgba(212, 175, 55, 0.25);
    color: #D4AF37;
    font-family: 'Cinzel', serif;
    font-size: 0.8125rem;          /* V0 text-[9px] */
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.35em;
    opacity: 0;
    transform: scale(0.9);
    animation: manualEyebrowIn 0.4s ease 0.2s forwards;
}
.manual-eyebrow-dot {
    width: 6px; height: 6px;
    border-radius: 50%;
    background: #D4AF37;
    box-shadow: 0 0 8px rgba(212, 175, 55, 0.8);
}
@keyframes manualEyebrowIn {
    to { opacity: 1; transform: scale(1); }
}

/* Title block — has its own darkened backdrop with gold-line top + bottom. */
.manual-title-block {
    display: inline-block;
    position: relative;
    padding: 0.75rem 3rem;
    margin-bottom: 0.75rem;
    background: linear-gradient(90deg,
        transparent 0%,
        rgba(8, 5, 2, 0.82) 28%,
        rgba(8, 5, 2, 0.88) 50%,
        rgba(8, 5, 2, 0.82) 72%,
        transparent 100%);
}
.manual-title-block::before,
.manual-title-block::after {
    content: '';
    position: absolute;
    inset-inline: 0;
    height: 1px;
    pointer-events: none;
    background: linear-gradient(90deg,
        transparent 0%,
        rgba(212, 175, 55, 0.28) 35%,
        rgba(212, 175, 55, 0.28) 65%,
        transparent 100%);
}
.manual-title-block::before { top: 0; }
.manual-title-block::after  { bottom: 0; }

.manual-title {
    position: relative;
    z-index: 1;
    font-family: 'Cinzel', serif;
    font-size: 1.5rem;             /* V0 text-2xl md:text-4xl */
    font-weight: 900;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    margin: 0;
    background: linear-gradient(180deg, #FFF8E7 0%, #F4E287 30%, #D4AF37 65%, #9A7515 100%);
    -webkit-background-clip: text;
    background-clip: text;
    -webkit-text-fill-color: transparent;
    color: transparent;
    filter: drop-shadow(0 2px 14px rgba(212, 175, 55, 0.35));
}
@media (min-width: 768px) {
    .manual-title { font-size: 2.25rem; }
}

.manual-sub {
    font-family: 'Inter', sans-serif;
    font-size: 1rem;                /* page standfirst — reads as intro copy */
    color: rgba(214, 196, 158, 0.95);
    max-width: 34rem;
    margin: 0 auto;
    line-height: 1.6;
}

.manual-divider {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 1rem;
    margin-top: 1.5rem;
}
.manual-divider .line {
    flex: 1 1 0;
    max-width: 6rem;
    height: 1px;
    background: linear-gradient(90deg, transparent, rgba(212, 175, 55, 0.30));
}
.manual-divider .line + .line {
    background: linear-gradient(90deg, rgba(212, 175, 55, 0.30), transparent);
}
.manual-divider .glyph {
    color: rgba(212, 175, 55, 0.85);
    display: inline-flex;
    align-items: center;
}

/* ─── Card grid (2×2) ────────────────────────────────────────────────────── */
.manual-grid {
    display: grid;
    grid-template-columns: 1fr;
    gap: 1.25rem;
    opacity: 0;
    animation: manualFadeIn 0.4s ease 0.2s forwards;
}
@media (min-width: 768px) {
    .manual-grid { grid-template-columns: 1fr 1fr; }
}
@media (min-width: 1180px) {
    .manual-grid { grid-template-columns: repeat(4, 1fr); gap: 1rem; }
}
@keyframes manualFadeIn {
    to { opacity: 1; }
}

/* ─── Individual card ────────────────────────────────────────────────────── */
.manual-card {
    --accent: #D4AF37;
    position: relative;
    display: flex;
    flex-direction: column;
    width: 100%;
    border-radius: 0.75rem;
    overflow: hidden;
    cursor: pointer;
    padding: 0;
    text-align: center;
    color: inherit;

    background: linear-gradient(165deg, rgba(32, 24, 14, 0.72) 0%, rgba(16, 12, 7, 0.82) 100%);
    backdrop-filter: blur(14px);
    -webkit-backdrop-filter: blur(14px);
    border: 1px solid rgba(212, 175, 55, 0.20);
    box-shadow:
        0 8px 32px rgba(0, 0, 0, 0.4),
        inset 0 1px 0 rgba(212, 175, 55, 0.08);

    transition:
        transform 0.3s cubic-bezier(0.25, 0.46, 0.45, 0.94),
        border-color 0.25s ease,
        box-shadow 0.25s ease;

    /* Staggered fade-in driven by --stagger (set inline on each card). */
    opacity: 0;
    transform: translateY(28px);
    animation: manualCardIn 0.45s ease-out forwards;
    animation-delay: calc(0.18s + var(--stagger, 0) * 0.1s);
}
@keyframes manualCardIn {
    to { opacity: 1; transform: translateY(0); }
}

.manual-card.is-primary {
    background: linear-gradient(165deg, rgba(42, 32, 18, 0.78) 0%, rgba(20, 15, 8, 0.85) 100%);
    border-color: color-mix(in srgb, var(--accent) 33%, transparent);
    box-shadow:
        0 0 20px color-mix(in srgb, var(--accent) 8%, transparent),
        0 10px 36px rgba(0, 0, 0, 0.45),
        inset 0 1px 0 color-mix(in srgb, var(--accent) 10%, transparent);
}

/* Ambient halo behind primary cards — pulses slowly. */
.manual-card-ambient {
    position: absolute;
    inset: -0.5rem;
    border-radius: 1rem;
    z-index: -1;
    pointer-events: none;
    filter: blur(60px);
    background: radial-gradient(ellipse at 50% 60%,
        color-mix(in srgb, var(--accent) 16%, transparent) 0%,
        color-mix(in srgb, var(--accent) 7%, transparent) 50%,
        transparent 80%);
    animation: manualAmbientPulse 4s ease-in-out infinite;
}
@keyframes manualAmbientPulse {
    0%, 100% { opacity: 0.5; }
    50%      { opacity: 0.9; }
}

/* Top shimmer line on each card. */
.manual-card-shimmer {
    position: absolute;
    top: 0;
    right: 1.5rem;
    left: 1.5rem;
    height: 1px;
    pointer-events: none;
    background: linear-gradient(90deg,
        transparent,
        color-mix(in srgb, var(--accent) 33%, transparent),
        transparent);
}

/* Badge ribbon ("Essential", "Advanced") at the top of badged cards. */
.manual-card-badge {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0.5rem;
    padding: 0.375rem 0;
    font-family: 'Cinzel', serif;
    font-size: 0.8125rem;              /* V0 text-[8px] */
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.35em;
    color: var(--accent);
    background: linear-gradient(90deg,
        transparent 0%,
        color-mix(in srgb, var(--accent) 12%, transparent) 20%,
        color-mix(in srgb, var(--accent) 16%, transparent) 50%,
        color-mix(in srgb, var(--accent) 12%, transparent) 80%,
        transparent 100%);
    border-bottom: 1px solid color-mix(in srgb, var(--accent) 19%, transparent);
}
.manual-card-badge .dot {
    width: 4px;
    height: 4px;
    border-radius: 50%;
    background: var(--accent);
    box-shadow: 0 0 6px var(--accent);
}

/* Card body — centered column. */
.manual-card-body {
    display: flex;
    flex-direction: column;
    align-items: center;
    padding: 1.25rem;
    height: 100%;
}

/* Icon tile at top of body. */
.manual-card-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 3rem;
    height: 3rem;
    flex-shrink: 0;
    margin-bottom: 1rem;
    border-radius: 0.5rem;
    color: color-mix(in srgb, var(--accent) 60%, transparent);
    background: color-mix(in srgb, var(--accent) 7%, transparent);
    border: 1px solid color-mix(in srgb, var(--accent) 15%, transparent);
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.03);
    transition: transform 0.25s ease,
                background-color 0.25s ease,
                border-color 0.25s ease,
                box-shadow 0.25s ease,
                color 0.25s ease,
                filter 0.25s ease;
}

/* Designer pass (2026-05-20): bumped all the "small print" inside the four
   manual category cards. Original sizes (0.5rem / 0.625rem) were lifted
   from V0's text-[8px] / text-[10px] which read fine on the V0 mock but
   are too small on a real display. Title kept at V0 size; only the
   supporting copy and the "click to open" marker grew. Opacity nudged
   up on subtitle/desc so the new sizes don't look washed out. */
/* Chapter numeral. Sits where the old "MANUAL" eyebrow did — same rhythm,
   but it marks reading order instead of repeating the page title four
   times. Measured against the composited card backdrop the accent at 80%
   left the red card at 4.36:1, under AA for text this size; 92% clears it
   on all four accents. */
.manual-card-numeral {
    font-family: 'Cinzel', serif;
    font-size: 0.875rem;
    font-weight: 700;
    letter-spacing: 0.24em;
    /* letter-spacing pads the right of the last glyph — pull it back so the
       numeral is optically centred over the icon above it. */
    text-indent: 0.24em;
    line-height: 1;
    /* No extra opacity here: 92% x 0.85 lands back at an effective 78% and
       returns the red card to 4.22:1. 92% alone measures 5.34:1 on the worst
       of the four accents. */
    color: color-mix(in srgb, var(--accent) 92%, transparent);
    margin: 0 0 0.5rem;
}

.manual-card-title {
    font-family: 'Cinzel', serif;
    font-size: 1.25rem;             /* V0 text-xl — kept */
    font-weight: 700;
    letter-spacing: 0.1em;
    line-height: 1.35;
    color: #EDD98A;
    margin: 0;
    transition: text-shadow 0.3s ease;
}

.manual-card-subtitle {
    font-family: 'Inter', sans-serif;
    font-size: 0.9375rem;
    line-height: 1.55;
    color: rgba(214, 196, 158, 0.95);
    margin: 0.5rem 0 0;
    transition: color 0.3s ease;
}

.manual-card-desc {
    font-family: 'Inter', sans-serif;
    font-size: 0.9375rem;
    line-height: 1.55;
    color: rgba(206, 188, 150, 0.92);
    /* Tightened with the type bump so the 2-line clamp still fits the card. */
    margin: 0.625rem 0 0;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

.manual-card-divider {
    display: block;
    width: 3rem;
    height: 1px;
    margin: 0.625rem 0;
    background: linear-gradient(90deg,
        transparent,
        color-mix(in srgb, var(--accent) 13%, transparent),
        transparent);
}

.manual-card-open {
    display: inline-flex;
    align-items: center;
    gap: 0.375rem;
    font-family: 'Cinzel', serif;
    /* The card's call to action — previously the hardest line on the page:
       small, widely tracked AND dimmed to 75%. Bigger, tighter, full gold. */
    font-size: 0.9375rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.12em;
    color: rgba(212, 175, 55, 0.95);
    opacity: 1;
    transition: color 0.25s ease;
    margin-top: auto;
}

/* ─── Hover state ────────────────────────────────────────────────────────── */
.manual-card:hover,
.manual-card:focus-visible {
    transform: translateY(-6px) scale(1.02);
    border-color: color-mix(in srgb, var(--accent) 53%, transparent);
    box-shadow:
        0 0 28px color-mix(in srgb, var(--accent) 14%, transparent),
        0 12px 40px rgba(0, 0, 0, 0.5),
        inset 0 1px 0 color-mix(in srgb, var(--accent) 13%, transparent);
    outline: none;
}
.manual-card:hover .manual-card-icon,
.manual-card:focus-visible .manual-card-icon {
    background: color-mix(in srgb, var(--accent) 13%, transparent);
    border-color: color-mix(in srgb, var(--accent) 33%, transparent);
    box-shadow:
        0 0 24px color-mix(in srgb, var(--accent) 19%, transparent),
        inset 0 1px 0 rgba(255, 255, 255, 0.06);
    color: var(--accent);
    transform: scale(1.08);
    filter: drop-shadow(0 0 6px color-mix(in srgb, var(--accent) 37%, transparent));
}
.manual-card:hover .manual-card-title,
.manual-card:focus-visible .manual-card-title {
    text-shadow: 0 0 20px color-mix(in srgb, var(--accent) 25%, transparent);
}
.manual-card:hover .manual-card-subtitle,
.manual-card:focus-visible .manual-card-subtitle {
    color: rgba(220, 200, 155, 0.9);
}
.manual-card:hover .manual-card-open,
.manual-card:focus-visible .manual-card-open {
    color: var(--accent);
    opacity: 1;
}

/* Active tap feedback on mobile. */
.manual-card:active {
    transform: translateY(-2px) scale(0.99);
    transition-duration: 0.12s;
}

/* ─── Wide-desktop trim ──────────────────────────────────────────────────
   Must live AFTER the base rules above: a media query carries no extra
   specificity, so the same block written earlier in the file loses to the
   plain rule it is trying to override. */
@media (min-width: 1180px) {
    /* 34rem was chosen for a 64rem panel; in a 76rem one it left the
       standfirst wrapping to two lines with clear space either side. */
    .manual-sub { max-width: 46rem; }
    /* Cards are ~246px across in the 4-across row. The clamped description
       needs that horizontal padding as reading width more than the card
       needs air. */
    .manual-card-body { padding: 1rem 0.875rem 1.125rem; }
    .manual-card-icon { margin-bottom: 0.75rem; }
}

/* ─── Reduced-motion safety ──────────────────────────────────────────────── */
@media (prefers-reduced-motion: reduce) {
    .manual-panel,
    .manual-header-icon,
    .manual-eyebrow,
    .manual-grid,
    .manual-card { animation: none; opacity: 1; transform: none; }
    .manual-card-ambient { animation: none; opacity: 0.5; }
    .manual-card:hover,
    .manual-card:focus-visible { transform: none; }
}

/* ════════════════════════════════════════════════════════════════════════════
   PHASE 2 — Modal + Tribes content
   ──────────────────────────────────────────────────────────────────────────── */

/* ─── Modal root + backdrop ──────────────────────────────────────────────── */
.manual-modal-root {
    position: fixed;
    inset: 0;
    z-index: 200;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 1rem;
}
@media (min-width: 768px) {
    .manual-modal-root { padding: 1.5rem; }
}

.manual-modal-backdrop {
    position: absolute;
    inset: 0;
    background: rgba(0, 0, 0, 0.7);
    backdrop-filter: blur(8px);
    -webkit-backdrop-filter: blur(8px);
    /* No transition on backdrop-filter — same reasoning as landing-atmos-dim,
       transitioning compositor properties causes flicker on tab return. */
}

.manual-modal {
    position: relative;
    z-index: 10;
    width: 100%;
    max-width: 64rem;
    max-height: 90vh;
    display: flex;
    align-items: stretch;
    justify-content: center;
}

/* ─── Modal panel ────────────────────────────────────────────────────────── */
.manual-modal-panel {
    position: relative;
    width: 100%;
    border-radius: 1rem;
    display: flex;
    flex-direction: column;
    max-height: 90vh;
    /*
     * `overflow: visible` (not hidden) so the "i" tooltip on the header can
     * extend above the panel. Without this it gets clipped at the panel
     * edge — visible only inside the modal, mostly cut off. Other clipping
     * still works because:
     *   • the rounded corners are enforced by the panel's own border-radius
     *     (the gradient bg + border follow it automatically)
     *   • the top/bottom shimmer bars have matching border-radius corners
     *   • `.manual-modal-content` has `overflow-y: auto` for its own scroll
     * Side-effect bonus: the top shimmer's 24px gold glow now haloes
     * subtly above the panel instead of being clipped flat.
     */
    overflow: visible;
    background: linear-gradient(170deg,
        rgba(22, 16, 10, 0.97) 0%,
        rgba(12, 9, 6, 0.98) 60%,
        rgba(18, 13, 8, 0.97) 100%);
    border: 1px solid rgba(212, 175, 55, 0.28);
    box-shadow:
        0 40px 100px rgba(0, 0, 0, 0.8),
        0 0 0 1px rgba(212, 175, 55, 0.06),
        inset 0 1px 0 rgba(212, 175, 55, 0.2);
}

/* Enter / leave transitions for the panel — Alpine class hooks. */
.manual-modal-enter        { transition: opacity 0.32s cubic-bezier(0.22, 1, 0.36, 1),
                                       transform 0.32s cubic-bezier(0.22, 1, 0.36, 1); }
.manual-modal-enter-start  { opacity: 0; transform: translateY(32px) scale(0.97); }
.manual-modal-enter-end    { opacity: 1; transform: translateY(0)    scale(1);    }
.manual-modal-leave        { transition: opacity 0.22s ease, transform 0.22s ease; }
.manual-modal-leave-start  { opacity: 1; transform: translateY(0)    scale(1);    }
.manual-modal-leave-end    { opacity: 0; transform: translateY(20px) scale(0.97); }

/* Top + bottom shimmer bars. */
/* Tinted by the same accent as the bloom, so the top edge reads as one light
   source rather than a gold bar sitting on a coloured wash. */
.manual-modal-shimmer {
    position: absolute;
    inset-inline: 0;
    top: 0;
    height: 2px;
    z-index: 4;
    pointer-events: none;
    background: linear-gradient(90deg,
        transparent 0%,
        var(--panel-accent, #D4AF37) 20%,
        color-mix(in srgb, var(--panel-accent, #D4AF37) 35%, #FFF8DC) 50%,
        var(--panel-accent, #D4AF37) 80%,
        transparent 100%);
    box-shadow: 0 0 24px color-mix(in srgb, var(--panel-accent, #D4AF37) 62%, transparent);
    transition: background 0.45s ease, box-shadow 0.45s ease;
    border-top-right-radius: 1rem;
    border-top-left-radius: 1rem;
}
.manual-modal-shimmer.bottom {
    top: auto;
    bottom: 0;
    height: 1px;
    background: linear-gradient(90deg,
        transparent,
        rgba(212, 175, 55, 0.25) 30%,
        rgba(212, 175, 55, 0.40) 50%,
        rgba(212, 175, 55, 0.25) 70%,
        transparent);
    box-shadow: none;
    border-radius: 0 0 1rem 1rem;
}

/* ─── Modal header ───────────────────────────────────────────────────────── */
/*
 * Slimmed from 110px to ~76px. The panel is capped at 90vh and the tribes tab
 * needs ~750px of content, so on a 900px-tall window there were only ~60px of
 * slack in the whole dialog - and a third of the header was spent on an eyebrow
 * reading "Game Manual", above a title, inside the Game Manual. Every pixel
 * reclaimed here is a pixel the body can spend on legible type instead.
 */
.manual-modal-header {
    flex-shrink: 0;
    display: flex;
    flex-direction: column;      /* identity row, then the per-tab command bar */
    align-items: stretch;
    padding: 0.875rem 1rem 0.75rem;
    border-bottom: 1px solid rgba(212, 175, 55, 0.12);
}
.manual-modal-header-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    min-width: 0;
}
@media (min-width: 640px) {
    .manual-modal-header { padding: 1rem 1.5rem 0.875rem; }
}

.manual-modal-head-left {
    display: flex;
    align-items: center;
    gap: 1rem;
    min-width: 0;
}

.manual-modal-head-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2.25rem;
    height: 2.25rem;
    flex-shrink: 0;
    border-radius: 0.75rem;
    background: rgba(212, 175, 55, 0.1);
    border: 1px solid rgba(212, 175, 55, 0.25);
    color: #D4AF37;
}

.manual-modal-head-text { min-width: 0; }

/*
 * Hidden, not deleted. It said "Game Manual" above the tab's own title, inside a
 * dialog opened from the Game Manual page - ~20px of header for a word the reader
 * already had three times over. Kept in the markup (and in every translation) so
 * restoring it is a one-line change if it is ever wanted back.
 */
.manual-modal-eyebrow {
    display: none;
    font-family: 'Cinzel', serif;
    font-size: 0.8125rem;
    text-transform: uppercase;
    letter-spacing: 0.35em;
    color: rgba(212, 175, 55, 0.85);
    margin: 0 0 0.125rem;
}

.manual-modal-title-row {
    display: flex;
    align-items: center;
    gap: 0.5rem;
}

.manual-modal-title {
    font-family: 'Cinzel', serif;
    font-size: 1.375rem;   /* 19.8px - see the type-scale note in the tribes section */
    font-weight: 700;
    letter-spacing: 0.15em;
    text-transform: uppercase;
    margin: 0;
    background: linear-gradient(180deg, #FFF8E7 0%, #F4E287 30%, #D4AF37 65%, #9A7515 100%);
    -webkit-background-clip: text;
    background-clip: text;
    -webkit-text-fill-color: transparent;
    color: transparent;
}

/* Info "i" with hover tooltip. */
.manual-modal-info {
    position: relative;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 1.25rem;
    height: 1.25rem;
    flex-shrink: 0;
    border-radius: 9999px;
    background: rgba(212, 175, 55, 0.1);
    border: 1px solid rgba(212, 175, 55, 0.3);
    color: rgba(212, 175, 55, 0.85);
    font-family: 'Cinzel', serif;
    font-size: 0.8125rem;
    font-weight: 700;
    cursor: default;
    user-select: none;
}
/*
 * The tip opens DOWNWARD, into the panel.
 *
 * It used to sit above the "i" (bottom: 100% + 0.75rem) and was clipped for every
 * visitor: the "i" lives in the panel header, the header is at the top of a panel
 * that is vertically centred and nearly as tall as the viewport, so there is never
 * 130px of room above it. Measured at 1024x860 the tip's top edge landed at -60px,
 * i.e. entirely off-screen, and slimming the header only pushes it further out.
 * Below the "i" it opens over the panel body, where the space is unbounded.
 */
.manual-modal-tip {
    position: absolute;
    top: calc(100% + 0.75rem);
    right: 50%;
    transform: translateX(50%);
    width: 20rem;
    max-width: min(20rem, 80vw);
    padding: 0.75rem 1rem;
    border-radius: 0.75rem;
    background: linear-gradient(160deg, rgba(22, 16, 10, 0.98), rgba(12, 9, 6, 0.99));
    border: 1px solid rgba(212, 175, 55, 0.25);
    box-shadow: 0 16px 48px rgba(0, 0, 0, 0.7), 0 0 0 1px rgba(212, 175, 55, 0.06);
    color: rgba(190, 170, 130, 0.82);
    font-family: 'Inter', sans-serif;
    font-size: 0.8125rem;
    line-height: 1.55;
    text-align: right;
    text-transform: none;
    letter-spacing: 0;
    pointer-events: none;
    opacity: 0;
    transition: opacity 0.18s ease;
    z-index: 50;
}
.manual-modal-info:hover .manual-modal-tip,
.manual-modal-info:focus-visible .manual-modal-tip { opacity: 1; }
/* arrow on the TOP edge now, so the two lit sides face the "i" above it */
.manual-modal-tip::before {
    content: '';
    position: absolute;
    top: -5px;
    right: 50%;
    transform: translateX(50%) rotate(45deg);
    width: 10px;
    height: 10px;
    background: rgba(22, 16, 10, 0.99);
    border-right: 1px solid rgba(212, 175, 55, 0.25);
    border-top: 1px solid rgba(212, 175, 55, 0.25);
}

.manual-modal-sub {
    font-family: 'Inter', sans-serif;
    font-size: 0.875rem;
    color: rgba(154, 130, 85, 0.85);
    margin: 0.125rem 0 0;
}

/*
 * Close button. A flat red squircle before - loud at rest, and its rounded-square
 * silhouette echoed the corner brackets that used to sit beside it, so the two
 * read as one dated cluster. Now a disc lit from above: it holds enough presence
 * to find without hunting, and on hover it fills, throws a red halo, and turns
 * the glyph a quarter turn so the X assembles under the cursor.
 */
.manual-modal-close {
    position: relative;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2.25rem;
    height: 2.25rem;
    flex-shrink: 0;
    border-radius: 50%;
    background:
        radial-gradient(circle at 50% 28%,
            rgba(248, 113, 113, 0.26) 0%,
            rgba(239, 68, 68, 0.12) 55%,
            rgba(239, 68, 68, 0.05) 100%);
    border: 1px solid rgba(239, 68, 68, 0.46);
    color: #FCA5A5;
    cursor: pointer;
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.07);
    transition: transform 0.24s cubic-bezier(0.34, 1.4, 0.64, 1),
                background 0.2s ease,
                border-color 0.2s ease,
                color 0.2s ease,
                box-shadow 0.24s ease;
}
.manual-modal-close:hover,
.manual-modal-close:focus-visible {
    background:
        radial-gradient(circle at 50% 28%,
            rgba(252, 165, 165, 0.55) 0%,
            rgba(239, 68, 68, 0.34) 55%,
            rgba(220, 38, 38, 0.20) 100%);
    border-color: rgba(252, 165, 165, 0.9);
    color: #FFFFFF;
    box-shadow: 0 0 20px rgba(239, 68, 68, 0.45),
                inset 0 1px 0 rgba(255, 255, 255, 0.16);
    transform: rotate(90deg) scale(1.06);
    outline: none;
}
.manual-modal-close:active { transform: rotate(90deg) scale(0.9); }
@media (prefers-reduced-motion: reduce) {
    .manual-modal-close:hover,
    .manual-modal-close:focus-visible,
    .manual-modal-close:active { transform: none; }
}

/* ─── Modal content area ─────────────────────────────────────────────────── */
.manual-modal-content {
    flex: 1 1 auto;
    min-height: 0;
    padding: 1rem;
    overflow-y: auto;
}
@media (min-width: 640px) {
    .manual-modal-content { padding: 1.5rem 2rem; }
}
.manual-modal-content::-webkit-scrollbar { width: 8px; }
.manual-modal-content::-webkit-scrollbar-track { background: transparent; }
.manual-modal-content::-webkit-scrollbar-thumb {
    background: rgba(212, 175, 55, 0.18);
    border-radius: 8px;
}

/* Tab pane enter transition. */
.manual-tab-pane {
    display: flex;
    flex-direction: column;
    gap: 1rem;
}
.manual-tab-enter        { transition: opacity 0.22s ease, transform 0.22s ease; }
.manual-tab-enter-start  { opacity: 0; transform: translateX(-12px); }
.manual-tab-enter-end    { opacity: 1; transform: translateX(0);     }

.manual-tab-stub {
    padding: 3rem 1rem;
    text-align: center;
}
.manual-tab-stub .muted {
    font-family: 'Inter', sans-serif;
    font-size: 0.8125rem;
    color: rgba(190, 170, 130, 0.85);
}

/* ─── Tribes — tribe selector cards ──────────────────────────────────────── */
.tribe-picker {
    display: grid;
    /* auto-fit, NOT repeat(3, 1fr): a round runs either three tribes or five, and the
       hardcoded three dropped the Egyptians and Huns onto a second row two cards wide. */
    grid-template-columns: repeat(auto-fit, minmax(9.5rem, 1fr));
    gap: 0.75rem;
}

.tribe-pick {
    --tribe-color: #D4AF37;
    position: relative;
    height: 130px;
    border-radius: 0.75rem;
    overflow: hidden;
    cursor: pointer;
    padding: 0;
    background: linear-gradient(160deg, rgba(18, 13, 6, 0.8) 0%, rgba(10, 7, 3, 0.9) 100%);
    border: 1px solid rgba(212, 175, 55, 0.1);
    /* NOT dimmed as a whole any more. `opacity: 0.45` here dragged the LABEL down with
       the card and left it at 2.16:1 contrast, well under the 4.5:1 minimum - the tribe
       name was the one thing that always had to stay readable. Unselected state is now
       carried by the portrait (greyscale) and by the border/background below, both of
       which are decoration rather than text. */
    opacity: 1;
    transform: scale(1);
    transition: opacity 0.25s ease,
                transform 0.25s cubic-bezier(0.34, 1.56, 0.64, 1),
                border-color 0.25s ease,
                box-shadow 0.25s ease,
                background 0.25s ease;
}
.tribe-pick:hover { transform: scale(1.04); border-color: color-mix(in srgb, var(--tribe-color) 30%, transparent); }
.tribe-pick:active { transform: scale(0.97); transition-duration: 0.12s; }

.tribe-pick.is-active {
    opacity: 1;
    transform: scale(1.02);
    background: linear-gradient(180deg, rgba(10, 7, 3, 0.6) 0%, color-mix(in srgb, var(--tribe-color) 15%, transparent) 100%);
    border-color: color-mix(in srgb, var(--tribe-color) 40%, transparent);
    box-shadow:
        0 0 24px color-mix(in srgb, var(--tribe-color) 15%, transparent),
        inset 0 1px 0 color-mix(in srgb, var(--tribe-color) 13%, transparent);
}

.tribe-pick-shimmer {
    position: absolute;
    inset-inline: 0;
    top: 0;
    height: 1px;
    pointer-events: none;
    opacity: 0;
    background: linear-gradient(90deg, transparent, color-mix(in srgb, var(--tribe-color) 53%, transparent) 40%, color-mix(in srgb, var(--tribe-color) 53%, transparent) 60%, transparent);
    transition: opacity 0.25s ease;
}
.tribe-pick.is-active .tribe-pick-shimmer { opacity: 1; }

/* ─── Tribe portrait ─────────────────────────────────────────────────────────
 *
 * The task-master figure for each tribe, the same artwork the in-game quest advisor
 * uses. Source is img/q/l<tribeId>.jpg, a flat JPEG on WHITE; tools/make_transparent_portrait.php
 * cuts the background out (flood fill from the edges, never "all white pixels" - these
 * drawings are full of interior white) and writes a transparent PNG here.
 *
 * Bottom-anchored and contained, so the five figures - which differ in width from 100px
 * to 166px - all stand on the same baseline instead of floating at different heights.
 * The halo sits BEHIND the figure and is the only thing tinted per tribe.
 */
.tribe-crest-halo {
    position: absolute;
    right: 50%;
    bottom: 1.1rem;
    width: 5.5rem;
    height: 5.5rem;
    transform: translateX(50%) scale(0.7);
    border-radius: 50%;
    pointer-events: none;
    background: radial-gradient(circle,
        color-mix(in srgb, var(--tribe-color) 38%, transparent) 0%,
        transparent 70%);
    opacity: 0;
    transition: opacity 0.3s ease, transform 0.45s cubic-bezier(0.34, 1.56, 0.64, 1);
}

.tribe-pick-img {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: contain;
    object-position: bottom;
    padding: 0.5rem 0.75rem 1.4rem;   /* bottom clears the label strip */
    filter: grayscale(55%) brightness(0.85);
    transform: translateZ(0);
    transition: filter 0.28s ease, transform 0.32s cubic-bezier(0.34, 1.56, 0.64, 1);
}

/* hover: the figure wakes up and lifts slightly */
.tribe-pick:hover .tribe-crest-halo { opacity: 0.55; transform: translateX(50%) scale(1); }
.tribe-pick:hover .tribe-pick-img   { filter: grayscale(0%) brightness(1); transform: translateY(-3px); }

/* active: full colour, brighter bloom */
.tribe-pick.is-active .tribe-crest-halo { opacity: 0.8; transform: translateX(50%) scale(1.05); }
.tribe-pick.is-active .tribe-pick-img {
    filter: grayscale(0%) brightness(1.03)
            drop-shadow(0 4px 12px color-mix(in srgb, var(--tribe-color) 35%, transparent));
    transform: translateY(-3px);
}

/* staggered entrance, 45ms apart - inside the 30-50ms band that reads as one gesture
   rather than a queue. Runs once on load; --i comes from the template. */
.tribe-pick {
    animation: tribe-pick-in 0.45s cubic-bezier(0.22, 1, 0.36, 1) backwards;
    animation-delay: calc(var(--i, 0) * 45ms);
}
@keyframes tribe-pick-in {
    from { opacity: 0; transform: translateY(10px) scale(0.96); }
}

/* Keyboard focus must be visible and must not be the hover treatment - these are tabs. */
.tribe-pick:focus-visible {
    outline: 2px solid color-mix(in srgb, var(--tribe-color) 85%, transparent);
    outline-offset: 3px;
    opacity: 1;
}

.tribe-pick-label-wrap {
    position: absolute;
    inset-inline: 0;
    bottom: 0;
    z-index: 1;
    padding: 1rem 0.5rem 0.5rem;
    background: linear-gradient(0deg, rgba(0, 0, 0, 0.75) 0%, transparent 100%);
    pointer-events: none;
}
.tribe-pick-label {
    display: block;
    text-align: center;
    font-family: 'Cinzel', serif;
    font-size: 0.875rem;              /* 12.6px */
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.25em;
    /* ALWAYS the tribe colour. Every one of the five scores 7.1:1 to 11.8:1 against the
       panel background, so the name is legible whether or not the tribe is selected -
       which was the whole complaint. Selection is signalled by weight/glow instead of
       by turning the text on. */
    color: var(--tribe-color);
    text-shadow: 0 1px 3px rgba(0, 0, 0, 0.9);
    opacity: 0.78;
    transition: opacity 0.25s ease, text-shadow 0.25s ease, letter-spacing 0.25s ease;
}
.tribe-pick:hover .tribe-pick-label { opacity: 1; }
.tribe-pick.is-active .tribe-pick-label {
    opacity: 1;
    letter-spacing: 0.28em;
    text-shadow: 0 1px 3px rgba(0, 0, 0, 0.9),
                 0 0 14px color-mix(in srgb, var(--tribe-color) 55%, transparent);
}

/* ─── Tribes — body (overview + perks / troop table) ─────────────────────── */
/*
 * The three tribe panes (Romans/Gauls/Teutons) share one grid cell so the
 * fade-in/fade-out crossfade happens in-place instead of stacking. Without
 * this both panes briefly live in the document flow during the 180ms
 * Alpine opacity transition and the modal content height ~doubles — visible
 * as a sudden expansion mid-transition. With grid-area overlap, the
 * container's height is the tallest pane (all three have 10 troops →
 * effectively identical heights), and only opacity animates.
 */
.tribe-body {
    display: grid;
    grid-template-columns: 1fr;
    grid-template-rows: auto;
}

.tribe-body-pane {
    /* Every pane occupies the same cell and STAYS there - hidden ones are not removed
       from layout, so the row is permanently as tall as the tallest tribe and the panel
       never grows or shrinks between clicks. */
    grid-column: 1 / -1;
    grid-row: 1;

    display: grid;
    grid-template-columns: 1fr;
    gap: 1rem;
    min-height: 0;

    /* hidden state: parked one step along the axis of travel */
    opacity: 0;
    visibility: hidden;
    pointer-events: none;
    transform: translate3d(calc(var(--dir, 1) * 2.25rem), 0, 0) scale(0.985);
    transition: opacity 0.26s cubic-bezier(0.4, 0, 0.2, 1),
                transform 0.42s cubic-bezier(0.22, 1, 0.36, 1),
                visibility 0s linear 0.28s;
}

.tribe-body-pane.is-shown {
    opacity: 1;
    visibility: visible;
    pointer-events: auto;
    transform: none;
    /* entering is the moment worth seeing, so it gets the longer curve; visibility flips
       immediately on the way IN and is delayed on the way out so the fade can finish */
    transition: opacity 0.34s cubic-bezier(0.22, 1, 0.36, 1),
                transform 0.46s cubic-bezier(0.22, 1, 0.36, 1),
                visibility 0s;
}

/* the perk bullets arrive just behind the panel, 45ms apart - one gesture, not a queue */
.tribe-body-pane.is-shown .tribe-perks li {
    animation: tribe-perk-in 0.4s cubic-bezier(0.22, 1, 0.36, 1) backwards;
    animation-delay: calc(0.08s + var(--i, 0) * 45ms);
}
@keyframes tribe-perk-in {
    from { opacity: 0; transform: translateX(calc(var(--dir, 1) * 0.6rem)); }
}
@media (min-width: 768px) {
    .tribe-body-pane { grid-template-columns: 0.9fr 2.25fr; }
}

.tribe-left {
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
}

/*
 * ── TRIBES TYPE SCALE ────────────────────────────────────────────────────────
 * The shell runs html { font-size: 14.4px } (90% of 16), so every rem here is a
 * tenth smaller than it reads in the source: what looks like "13px" rendered at
 * 11.7px, and the tribe copy and troop numbers were sitting at 11.7-12.6px.
 *
 * Sizes below are one step up, but the panel is height-bound (90vh cap, ~750px
 * of content), so the increase is PAID FOR rather than simply added - see the
 * density trims here and the width rules further down. Measured effect at 1600px
 * wide: the panel needs 713px where it used to need 750px, so the type got
 * bigger and the scrollbar threshold moved DOWN, from a 834px-tall window to 793.
 *
 * The full step is gated to >=1000px. Below that there is no spare width to trade
 * for it, and going the whole way cost +94px - enough to introduce a scrollbar on
 * an 860px-wide laptop that fits today. Narrow widths get the half step instead.
 */
.tribe-section {
    padding: 0.875rem;
    border-radius: 0.75rem;
    background: linear-gradient(160deg, rgba(18, 13, 6, 0.7) 0%, rgba(10, 7, 3, 0.8) 100%);
    border: 1px solid rgba(212, 175, 55, 0.14);
    box-shadow: inset 0 2px 12px rgba(0, 0, 0, 0.4);
}
.tribe-section-head {
    font-family: 'Cinzel', serif;
    font-size: 0.875rem;              /* 12.6px */
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.28em;
    color: rgba(212, 175, 55, 0.85);
    margin: 0 0 0.75rem;
}
.tribe-blurb {
    font-family: 'Inter', sans-serif;
    font-size: 0.9375rem;           /* 13.5px; steps to 1rem / 14.4px at >=1000px */
    line-height: 1.65;
    color: rgba(210, 190, 145, 0.88);
    margin: 0;
}

.tribe-perks {
    --tribe-color: #D4AF37;
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 0.375rem;
}
.tribe-perks li {
    display: flex;
    align-items: flex-start;
    gap: 0.5rem;
}
.tribe-perks .dot {
    flex-shrink: 0;
    width: 4px;
    height: 4px;
    margin-top: 0.4375rem;
    border-radius: 50%;
    background: var(--tribe-color);
    box-shadow: 0 0 4px color-mix(in srgb, var(--tribe-color) 50%, transparent);
}
.tribe-perks li span:last-child {
    font-family: 'Inter', sans-serif;
    font-size: 0.875rem;            /* 12.6px; steps to 0.9375rem / 13.5px at >=1000px */
    line-height: 1.5;
    color: rgba(210, 190, 145, 0.85);
}

/* ─── Tribes — troop table ───────────────────────────────────────────────── */
.tribe-right {
    border-radius: 0.75rem;
    overflow: hidden;
    border: 1px solid rgba(212, 175, 55, 0.14);
    background: linear-gradient(160deg, rgba(18, 13, 6, 0.7) 0%, rgba(10, 7, 3, 0.8) 100%);
}
.tribe-table-head {
    padding: 0.625rem 0.875rem;
    border-bottom: 1px solid rgba(212, 175, 55, 0.1);
    font-family: 'Cinzel', serif;
    font-size: 0.875rem;              /* 12.6px */
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.28em;
    color: rgba(212, 175, 55, 0.85);
}
.tribe-table-wrap {
    overflow-x: auto;
}
.tribe-table {
    width: 100%;
    border-collapse: collapse;
    font-family: 'Inter', sans-serif;
    /* FIXED, so the <colgroup> widths are authoritative and identical for every tribe.
       With the default `auto` the browser sizes columns to content: the Unit column
       followed the longest unit name (12 chars for the Huns, 19 for the Romans) and the
       remaining width was redistributed, so every number moved when you switched tribe. */
    table-layout: fixed;
}

/* Column widths, MEASURED in the browser at the >=1000px step (15px body size),
   not estimated: "Equites Imperatoris" needs 135px, a six-figure cost ("45,000") 50px
   and the longest training time ("25h 11m") 64px, so the ten columns need ~615px of
   table. The split below plus the wider table pane below gives 622px at a 1045px
   viewport with ZERO clipped cells, and 771px at 1280px. Percentages rather than px
   so the table still adapts to the panel. */
.tribe-table col.col-unit { width: 26%; }
.tribe-table col.col-stat { width: 5.65%; }
.tribe-table col.col-res  { width: 9.375%; }
.tribe-table col.col-spd  { width: 5%; }
/* Training-time column. The other nine columns are pure numerals; this one
   carries a short "33m 20s" string, so it is the widest of the non-name
   columns and the rest give up a little to pay for it. */
.tribe-table col.col-time { width: 13.5%; }
.tribe-table td.time {
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
    cursor: help;                 /* the cell's title() carries the exact seconds */
}
/* The line under each tribe's table: which speed and which building level the
   times above assume. Without it the column is only true on an x1 world, so it is
   NOT a footnote to be skimmed past - it gets the same bordered treatment as the
   panel's own callouts, with the hourglass that marks time everywhere else on the
   site. Flex + gap only, so the RTL twin needs no mirrored variant. */
.tribe-table-note {
    display: flex;
    align-items: center;          /* icon centred against the whole block, not line 1 */
    justify-content: center;      /* and the icon+text pair centred in the card */
    text-align: center;
    gap: 0.5rem;
    /* Inset on every side: the note is a box INSIDE the card, so it must not
       share an edge with the card's own border. */
    margin: 0.875rem 0.75rem 0.75rem;
    padding: 0.625rem 0.875rem;
    border-radius: 0.5rem;
    background: linear-gradient(180deg, rgba(212, 175, 55, 0.07), rgba(212, 175, 55, 0.02));
    border: 1px solid rgba(212, 175, 55, 0.16);
    font-family: 'Inter', sans-serif;
    font-size: 0.8125rem;
    line-height: 1.6;
    color: rgba(214, 193, 150, 0.88);
}
.tribe-table-note-icon {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 1.25rem;
    height: 1.25rem;
    margin-top: 0.1rem;
    border-radius: 50%;
    background: rgba(212, 175, 55, 0.12);
    border: 1px solid rgba(212, 175, 55, 0.3);
    color: #D4AF37;
}

/* ── Phones and small tablets ────────────────────────────────────────────────
   A ten-column table cannot honestly fit 375px: forced to 100% width it gave
   every column ~30px and the numbers printed straight over each other (measured:
   74 overflowing cells). The table keeps its real size instead and its wrapper
   scrolls - the wrapper has had overflow-x:auto all along, but `width:100%` on a
   table-layout:fixed table meant it never had anything to scroll. 37rem is the
   measured floor at this font (375px viewport, en and he): every name and every
   figure fits with nothing clipped, in every language including Hebrew. */
@media (max-width: 900px) {
    .tribe-table { min-width: 37rem; }
    /* The bar itself: thin, gold, and always drawn (Android/desktop). iOS hides
       overlay scrollbars until you touch, which is why the fades below exist. */
    .tribe-table-wrap {
        padding-bottom: 0.375rem;
        scrollbar-width: thin;
        scrollbar-color: rgba(212, 175, 55, 0.5) rgba(212, 175, 55, 0.1);
    }
    .tribe-table-wrap::-webkit-scrollbar        { height: 6px; }
    .tribe-table-wrap::-webkit-scrollbar-track  { background: rgba(212, 175, 55, 0.1); border-radius: 999px; }
    .tribe-table-wrap::-webkit-scrollbar-thumb  { background: rgba(212, 175, 55, 0.5); border-radius: 999px; }
    /* Edge fades = "there is more table this way". The classes are toggled from
       the page's own scroll handler, so a fade never lies: at either end of the
       scroll its side simply has no fade. */
    .tribe-table-wrap.has-more-right {
        -webkit-mask-image: linear-gradient(to right, #000 calc(100% - 2.25rem), rgba(0, 0, 0, 0.15) 100%);
                mask-image: linear-gradient(to right, #000 calc(100% - 2.25rem), rgba(0, 0, 0, 0.15) 100%);
    }
    .tribe-table-wrap.has-more-left {
        -webkit-mask-image: linear-gradient(to left, #000 calc(100% - 2.25rem), rgba(0, 0, 0, 0.15) 100%);
                mask-image: linear-gradient(to left, #000 calc(100% - 2.25rem), rgba(0, 0, 0, 0.15) 100%);
    }
    .tribe-table-wrap.has-more-left.has-more-right {
        -webkit-mask-image: linear-gradient(to right, rgba(0, 0, 0, 0.15) 0, #000 2.25rem, #000 calc(100% - 2.25rem), rgba(0, 0, 0, 0.15) 100%);
                mask-image: linear-gradient(to right, rgba(0, 0, 0, 0.15) 0, #000 2.25rem, #000 calc(100% - 2.25rem), rgba(0, 0, 0, 0.15) 100%);
    }
    .tribe-table td,
    .tribe-table td.unit { font-size: 0.8125rem; }
    .tribe-table th      { font-size: 0.75rem; }
}
/* fixed layout clips rather than wraps, so keep the unit name on one line and let it
   ellipsise if a future name is longer than the column */
.tribe-table td.unit span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* ⚠ The rule above is necessary but NOT sufficient: `overflow` does nothing on an
   INLINE box, so a name longer than its column printed straight over the attack
   figure instead of ellipsising (owner screenshot, Gauls on a phone). The span has
   to become an inline-block with a real max-width, and the cell clips as a
   backstop so nothing can paint outside it whatever the icon costs. */
.tribe-table td.unit { overflow: hidden; }
.tribe-table td.unit > span {
    display: inline-block;
    max-width: calc(100% - 1.5rem);   /* 16px icon + its 0.5rem gap */
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.tribe-table thead tr {
    border-bottom: 1px solid rgba(212, 175, 55, 0.08);
}
/*
 * Header cells host the travian GIF icons (att_all/def_i/def_c + res 1-4)
 * plus a small "Spd" text fallback. Centering vertically with min-height
 * keeps the row consistent even though img/text mix.
 */
.tribe-table th {
    padding: 0.5rem 0.25rem;
    font-family: 'Cinzel', serif;
    font-size: 0.875rem;            /* the two text headers, "Unit" and "Spd" - the rest are sprites */
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: rgba(154, 130, 85, 0.85);
    text-align: center;
    vertical-align: middle;
}
.tribe-table th.unit { padding-right: 0.75rem; text-align: right; }
.tribe-table th .th-text {
    color: rgba(212, 175, 55, 0.85);
}

/*
 * Sprite-icons — 1:1 port of the rules in
 * /travian/assets/default/lang/en/compact.css (img.att_all, img.def_i,
 * img.def_c, img.r1-r4). De-scoped: `.ti.<key>` works anywhere in the
 * page (we use it both in the troop-table headers AND in building cost
 * pills). Apex copies of the source files live at:
 *   /assets/img/manual/icons/att_all.gif   (16×16)
 *   /assets/img/manual/icons/def_i.gif     (16×16)
 *   /assets/img/manual/icons/def_c.gif     (16×16)
 *   /assets/img/manual/icons/res2.gif      (sprite strip — 18×130)
 *
 * Using inline-block spans with background-image means no <img> 404 risk
 * if an icon is renamed, and lets us drop a tiny visual filter for the
 * dark background.
 */
.ti {
    display: inline-block;
    vertical-align: middle;
    background-repeat: no-repeat;
    /* Subtle outer-glow so the tiny sprites pop against the dark bg. */
    filter: drop-shadow(0 0 2px rgba(0, 0, 0, 0.7));
}
.ti.att_all,
.ti.def_i,
.ti.def_c {
    width: 16px;
    height: 16px;
}
.ti.att_all { background-image: url('/assets/img/manual/icons/att_all.gif'); }
.ti.def_i   { background-image: url('/assets/img/manual/icons/def_i.gif'); }
.ti.def_c   { background-image: url('/assets/img/manual/icons/def_c.gif'); }

/*
 * Resource sprite-strip — single GIF, 4 frames at known offsets.
 * (5th frame is "crop consumption" but we don't display it here.)
 */
.ti.r1,
.ti.r2,
.ti.r3,
.ti.r4 {
    width: 18px;
    height: 18px;
    background-image: url('/assets/img/manual/icons/res2.gif');
}
.ti.r1 { background-position: 0 -1px;   }   /* Lumber */
.ti.r2 { background-position: 0 -26px;  }   /* Clay   */
.ti.r3 { background-position: 0 -53px;  }   /* Iron   */
.ti.r4 { background-position: 0 -77px;  }   /* Crop   */

.tribe-table tbody tr {
    border-bottom: 1px solid rgba(212, 175, 55, 0.05);
    transition: background-color 0.18s ease;
}
.tribe-table tbody tr:nth-child(odd)  { background: rgba(0, 0, 0, 0.15); }
.tribe-table tbody tr:nth-child(even) { background: rgba(0, 0, 0, 0.30); }
.tribe-table tbody tr:hover { background: rgba(212, 175, 55, 0.05); }

.tribe-table td {
    /* vertical padding trimmed 0.5 -> 0.3125rem: 10 body rows plus the header row means
       every 1px here costs 22px of panel height, which is what buys the larger type */
    padding: 0.3125rem 0.25rem;
    text-align: center;
    font-size: 0.875rem;            /* 12.6px; steps to 0.9375rem / 13.5px at >=1000px */
    vertical-align: middle;
}
.tribe-table td.unit {
    padding-right: 0.75rem;
    padding-left: 0.625rem;
    text-align: right;
    white-space: nowrap;
    color: #E8D9B0;
    font-weight: 500;
    font-size: 0.875rem;            /* 12.6px; steps to 0.9375rem / 13.5px at >=1000px */
}

/*
 * ── The >=1000px step ────────────────────────────────────────────────────────
 * Everything here trades WIDTH for HEIGHT, which is why it is gated: at these
 * sizes the dialog can grow sideways, and a wider description column wraps into
 * fewer lines, which is what pays for the larger type without a scrollbar.
 *
 * Width is scoped to `.tab-tribes` on purpose. The tribes tab is two columns of
 * short strings and a numeric table, so it turns width straight into saved height;
 * the guides and FAQ tabs are long-form prose, where a wider measure is worse to
 * read, so they keep the original 64rem.
 *
 * The 1.3fr split (from 1fr) hands the extra width to the description column
 * rather than to the table, which already had room to spare. Measured at 1024px:
 * the panel needs 733px against a 750px baseline, and the troop table still does
 * not scroll horizontally.
 */
@media (min-width: 1000px) {
    /* Guides joins tribes on the wide shell. This is only safe because the guide
       prose is capped at 68ch - the extra width lands on tables, figures and the
       library sheet's grid (4 columns instead of 3), never on the line length. */
    .manual-modal.tab-tribes,
    .manual-modal.tab-guide  { max-width: min(76rem, 96vw); }

    .tribe-body-pane { grid-template-columns: 0.95fr 2.25fr; }

    .manual-modal.tab-tribes .manual-modal-title { font-size: 1.5rem; }
    .tribe-blurb                                 { font-size: 1rem; }
    .tribe-perks li span:last-child,
    .tribe-table td,
    .tribe-table td.unit                         { font-size: 0.9375rem; }
}
/* Per-unit sprite (assets/img/manual/icons/u/<tid>.gif) — lives before
   the unit name inline so the name reads "icon  Legionnaire". */
.tribe-table td.unit .unit-icon {
    display: inline-block;
    width: 16px;
    height: 16px;
    margin-left: 0.5rem;
    vertical-align: middle;
    filter: drop-shadow(0 0 2px rgba(0, 0, 0, 0.6));
}
.tribe-table td.unit > span {
    vertical-align: middle;
}

.tribe-table td.atk  { color: #F87171; font-weight: 600; }
.tribe-table td.defi { color: #60A5FA; }
.tribe-table td.defc { color: #93C5FD; }
.tribe-table td.res  { color: rgba(210, 190, 145, 0.85); }
.tribe-table td.spd  { color: #D4AF37; font-weight: 700; }

/* ─── Reduced-motion safety (modal + tribes) ─────────────────────────────── */
@media (prefers-reduced-motion: reduce) {
    .manual-modal-enter,
    .manual-modal-leave,
    .manual-tab-enter,
    .tribe-pick { transition: none !important; }
    .manual-modal-enter-start,
    .manual-modal-leave-end { opacity: 0; transform: none; }
    .manual-modal-enter-end,
    .manual-modal-leave-start { opacity: 1; transform: none; }

    /* The portrait keeps its LOOK (full colour, bloom) and loses only the MOVEMENT -
       the staggered entrance and the lift. Killing the colour transition too would make
       the active tribe snap from grey to colour rather than settle, which is not what
       reduced-motion asks for.
       ⚠ translateX(-50%) MUST survive on the halo: that is centring, not animation.
       Writing `transform: none` here slides the bloom half its own width off-centre. */
    .tribe-pick { animation: none !important; }
    /* Tribe switch keeps the CROSSFADE (it explains that the content replaced itself)
       and loses the slide and the staggered bullets, which are the parts that actually
       trouble a motion-sensitive reader. Panes still overlay, so nothing reflows. */
    .tribe-body-pane,
    .tribe-body-pane.is-shown {
        transform: none !important;
        transition: opacity 0.2s ease, visibility 0s !important;
    }
    .tribe-body-pane:not(.is-shown) { transition: opacity 0.2s ease, visibility 0s linear 0.2s !important; }
    .tribe-body-pane.is-shown .tribe-perks li { animation: none !important; }
    .tribe-crest-halo,
    .tribe-pick-img { transition: opacity 0.2s ease, filter 0.2s ease !important; }
    .tribe-pick:hover .tribe-pick-img,
    .tribe-pick.is-active .tribe-pick-img { transform: none; }
    .tribe-pick:hover .tribe-crest-halo,
    .tribe-pick.is-active .tribe-crest-halo { transform: translateX(50%) scale(1); }
}

/* ════════════════════════════════════════════════════════════════════════════
   PHASE 3 — Buildings content (carousel)
   ──────────────────────────────────────────────────────────────────────────── */

/*
 * Card wrapper — all 18 building cards stack in the same grid cell, same
 * trick as the tribe panes (`grid-area: 1 / 1`). Only one is visible via
 * x-show; the rest are display:none. During the crossfade transition both
 * are briefly in the cell, overlaid — container takes the height of the
 * taller one. Since every card has the same layout (image + head + desc
 * + costs), heights only vary by description length, but the explicit
 * min-height keeps the container from bouncing too much.
 */
.building-card-wrap {
    display: grid;
    grid-template-columns: 1fr;
    grid-template-rows: auto;
    min-height: 340px;
    border-radius: 0.75rem;
    border: 1px solid rgba(212, 175, 55, 0.14);
    background: linear-gradient(160deg, rgba(18, 13, 6, 0.7) 0%, rgba(10, 7, 3, 0.8) 100%);
    overflow: hidden;
}
.building-card {
    grid-column: 1 / -1;
    grid-row: 1;
    display: flex;
    flex-direction: column;
}

/* Enter/leave transitions on the card swap. */
.building-card-enter        { transition: opacity 0.28s cubic-bezier(0.22, 1, 0.36, 1),
                                          transform 0.28s cubic-bezier(0.22, 1, 0.36, 1); }
.building-card-enter-start  { opacity: 0; transform: translateX(-36px); }
.building-card-enter-end    { opacity: 1; transform: translateX(0);    }
.building-card-leave        { transition: opacity 0.22s ease, transform 0.22s ease; }
.building-card-leave-start  { opacity: 1; transform: translateX(0);    }
.building-card-leave-end    { opacity: 0; transform: translateX(36px); }

/* ─── Card top: image + title block ──────────────────────────────────────── */
.building-top {
    display: flex;
    align-items: stretch;
    border-bottom: 1px solid rgba(212, 175, 55, 0.1);
}

.building-image {
    flex-shrink: 0;
    width: 9rem;
    padding: 1rem;
    display: flex;
    align-items: center;
    justify-content: center;
    background: rgba(0, 0, 0, 0.25);
    border-left: 1px solid rgba(212, 175, 55, 0.1);
}
.building-image img {
    width: 5rem;
    height: 5rem;
    object-fit: contain;
    filter: drop-shadow(0 4px 16px rgba(212, 175, 55, 0.2));
}
.building-image-fallback {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 5rem;
    height: 5rem;
    border-radius: 0.5rem;
    border: 1px solid rgba(212, 175, 55, 0.15);
    color: rgba(212, 175, 55, 0.85);
}

.building-head {
    flex: 1 1 auto;
    display: flex;
    flex-direction: column;
    justify-content: center;
    padding: 1rem 1.25rem;
    gap: 0.25rem;
    min-width: 0;
}
.building-head-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
}
.building-counter {
    font-family: 'Cinzel', serif;
    font-size: 0.875rem;             /* 12.6px */
    text-transform: uppercase;
    letter-spacing: 0.3em;
    color: rgba(212, 175, 55, 0.85);
    margin: 0;
}
.building-nav-inline {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    flex-shrink: 0;
}
.building-title {
    font-family: 'Cinzel', serif;
    font-size: 1.375rem;
    font-weight: 700;
    letter-spacing: 0.1em;
    margin: 0.125rem 0 0;
    background: linear-gradient(180deg, #FFF8E7 0%, #D4AF37 100%);
    -webkit-background-clip: text;
    background-clip: text;
    -webkit-text-fill-color: transparent;
    color: transparent;
}
.building-prereqs {
    margin: 0.25rem 0 0;
    font-family: 'Inter', sans-serif;
    font-size: 0.875rem;             /* 12.6px */
    color: rgba(154, 130, 85, 0.85);
}
.building-prereqs span {
    color: rgba(210, 190, 145, 0.78);
}

/* ─── Arrow buttons (inline header + bottom strip) ───────────────────────── */
.building-arrow {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 1.75rem;
    height: 1.75rem;
    border-radius: 0.5rem;
    background: rgba(212, 175, 55, 0.07);
    border: 1px solid rgba(212, 175, 55, 0.2);
    color: rgba(212, 175, 55, 0.75);
    cursor: pointer;
    transition: transform 0.18s cubic-bezier(0.34, 1.56, 0.64, 1),
                background-color 0.18s ease,
                box-shadow 0.18s ease;
}
.building-arrow.lg { width: 2rem; height: 2rem; }
.building-arrow:hover {
    background: rgba(212, 175, 55, 0.14);
    box-shadow: 0 0 12px rgba(212, 175, 55, 0.2);
    transform: scale(1.12);
}
.building-arrow:active { transform: scale(0.88); }

/* ─── Card middle: description + tribe advantages ────────────────────────── */
.building-desc-section {
    padding: 1.125rem 1.25rem;
    border-bottom: 1px solid rgba(212, 175, 55, 0.08);
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
}
.building-section-head {
    font-family: 'Cinzel', serif;
    font-size: 0.875rem;             /* 12.6px - matches .tribe-section-head */
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.28em;
    color: rgba(212, 175, 55, 0.85);
    margin: 0;
}
.building-section-head.no-margin { margin-left: 0.75rem; }

/*
 * ── BUILDINGS TYPE SCALE ─────────────────────────────────────────────────────
 * Same 14.4px-root correction as the tribes panel: these values render a tenth
 * smaller than they read, so the card body was at 12.6px and every label at
 * 11.7px. Unlike the tribes panel this one is nowhere near its height limit -
 * measured 410px of content against 693px available on a 900px-tall window, so
 * ~283px spare - which is why the increase here needs no density trims to pay
 * for it. The cards are grid-stacked in one cell (see .building-card-wrap), so
 * the panel simply settles at the height of the wordiest building and stays put
 * as you page through them.
 */
.building-desc {
    font-family: 'Inter', sans-serif;
    font-size: 1rem;                 /* 14.4px - matches .tribe-blurb */
    line-height: 1.65;
    color: rgba(210, 190, 145, 0.88);
    margin: 0;
    /*
     * Reserves the tallest description so everything below it starts at a fixed Y.
     * Measured across the 18 buildings this block was 24px, 48px or 71px (1-3 lines)
     * and every section under it slid by the difference as you paged through.
     */
    min-height: 4.95em;              /* 3 lines x 1.65 line-height */
}

/*
 * ── A CARD THAT DOES NOT MOVE ────────────────────────────────────────────────
 * The wrapper was already a fixed height, so the panel never jolted - but inside
 * it everything drifted. The cost row, the one line people compare between
 * buildings, was measured at eight different offsets from the card top (201, 224,
 * 248, 303, 327, 351px): a 150px swing. Pinning it to the base of the card, with
 * the description height reserved above and the tribe section always present,
 * means all 18 cards now share one skeleton.
 */
.building-cost-row { margin-top: auto; }

/* The "no tribe difference" line is information, not emphasis - it stays quiet so
   the three buildings that DO differ still stand out when you reach them. */
.building-tribe-line.is-none p { color: rgba(160, 145, 115, 0.7); font-style: italic; }

.building-tribe {
    margin-top: 0.25rem;
    padding-top: 0.875rem;
    border-top: 1px solid rgba(212, 175, 55, 0.1);
}
.building-tribe .building-section-head {
    margin-bottom: 0.5rem;
}
.building-tribe-line {
    display: flex;
    align-items: flex-start;
    gap: 0.5rem;
    margin-bottom: 0.25rem;
}
.building-tribe-line .dot {
    flex-shrink: 0;
    width: 4px;
    height: 4px;
    margin-top: 0.5rem;
    border-radius: 50%;
    background: rgba(212, 175, 55, 0.4);
}
.building-tribe-line p {
    margin: 0;
    font-family: 'Inter', sans-serif;
    font-size: 0.9375rem;            /* 13.5px - matches the tribe perk bullets */
    line-height: 1.5;
    color: rgba(210, 190, 145, 0.85);
}

/* ─── Card bottom: cost pills row ────────────────────────────────────────── */
.building-cost-row {
    padding: 0.875rem 1.25rem;
    display: flex;
    align-items: center;
    gap: 0.75rem;
    flex-wrap: wrap;
}
.building-cost-divider {
    flex-shrink: 0;
    width: 1px;
    height: 1.25rem;
    background: rgba(212, 175, 55, 0.15);
}
.building-costs {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    flex-wrap: wrap;
}
.building-cost {
    display: inline-flex;
    /* center-align so the 18×18 sprite icon and the value number share
       a vertical midline (baseline doesn't work for empty sprite spans). */
    align-items: center;
    gap: 0.5rem;
    padding: 0.375rem 0.75rem;
    border-radius: 0.5rem;
    background: rgba(0, 0, 0, 0.25);
    border: 1px solid rgba(255, 255, 255, 0.04);
}
.building-cost .ti {
    /* The .ti sprite size + bg are inherited from the global .ti rules —
       this is just margin tuning if needed (no overrides currently). */
    flex-shrink: 0;
}
.building-cost .v {
    font-family: 'Cinzel', serif;
    font-size: 0.9375rem;
    font-weight: 700;
    line-height: 1;
}

/* ─── Building tiles inside the library sheet ────────────────────────────── */
/*
 * Replaces .building-strip / .building-pills / .building-pill - a horizontal
 * scroller whose 18 items needed 2,316px in an 808px window. A tile carries the
 * building's own artwork, which a text pill could not, so you recognise the
 * target by its picture rather than by reading 18 uppercase labels.
 */
.building-tile {
    display: flex;
    align-items: center;
    gap: 0.55rem;
    width: 100%;
    padding: 0.4rem 0.55rem;
    border-radius: 0.6rem;
    background: rgba(0, 0, 0, 0.3);
    border: 1px solid rgba(212, 175, 55, 0.1);
    color: rgba(200, 182, 142, 0.9);
    cursor: pointer;
    text-align: right;
    transition: background-color 0.18s ease, border-color 0.18s ease,
                color 0.18s ease, box-shadow 0.18s ease, transform 0.18s ease;
}
.building-tile:hover {
    background: rgba(212, 175, 55, 0.08);
    border-color: rgba(212, 175, 55, 0.32);
    color: #E8D9B0;
    transform: translateY(-1px);
}
.building-tile.is-active {
    background: rgba(212, 175, 55, 0.15);
    border-color: rgba(212, 175, 55, 0.55);
    color: #F4E287;
    box-shadow: 0 0 16px rgba(212, 175, 55, 0.18),
                inset 0 1px 0 rgba(212, 175, 55, 0.15);
}
.building-tile-thumb {
    flex-shrink: 0;
    display: inline-flex; align-items: center; justify-content: center;
    width: 2.25rem; height: 2.25rem;
    border-radius: 0.45rem;
    background: rgba(0, 0, 0, 0.45);
    border: 1px solid rgba(212, 175, 55, 0.14);
    overflow: hidden;
    color: rgba(212, 175, 55, 0.7);
}
.building-tile-thumb img { width: 100%; height: 100%; object-fit: contain; }
.building-tile-name {
    min-width: 0;
    font-family: 'Cinzel', serif;
    font-size: 0.875rem;             /* 12.6px */
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

/* ─── Mobile: stack image above title instead of side-by-side ────────────── */
@media (max-width: 600px) {
    .building-top { flex-direction: column; }
    .building-image {
        width: 100%;
        border-left: none;
        border-bottom: 1px solid rgba(212, 175, 55, 0.1);
    }
    .building-card-wrap { min-height: 0; }
}

/* ─── Reduced-motion safety ──────────────────────────────────────────────── */
@media (prefers-reduced-motion: reduce) {
    .building-card-enter,
    .building-card-leave,
    .building-tile { transition: none !important; }
    .building-card-enter-start,
    .building-card-leave-end { opacity: 0; transform: none; }
    .building-card-enter-end,
    .building-card-leave-start { opacity: 1; transform: none; }
    .building-tile:hover { transform: none; }
}

/* ════════════════════════════════════════════════════════════════════════════
   PHASE 4 — FAQ accordion
   ──────────────────────────────────────────────────────────────────────────── */

.faq-list {
    display: flex;
    flex-direction: column;
    gap: 1.75rem;
}

/* ─── Group ──────────────────────────────────────────────────────────────
 * A heading, a rule that runs to the count, then the rows. The heading is the
 * only thing on the tab set in the display face: it is a label, which is what
 * Cinzel is good at, while the questions below it are prose.
 */
.faq-group {
    --faq-color: #D4AF37;
    display: flex;
    flex-direction: column;
    gap: 0.5rem;

    opacity: 0;
    animation: faqItemIn 0.3s ease forwards;
    animation-delay: calc(var(--stagger, 0) * 60ms);
}

.faq-group-title {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    margin: 0 0 0.25rem;
    font-family: 'Cinzel', serif;
    font-size: 1rem;
    font-weight: 700;
    letter-spacing: 0.24em;
    text-transform: uppercase;
    color: var(--faq-color);
}
/* The rule takes the leftover width, so the count always sits at the right
   edge whatever the label's length in the active language. */
.faq-group-rule {
    flex: 1 1 auto;
    height: 1px;
    background: linear-gradient(90deg,
        color-mix(in srgb, var(--faq-color) 34%, transparent),
        rgba(212, 175, 55, 0.06) 70%,
        transparent);
}
.faq-group-count {
    flex-shrink: 0;
    font-family: 'Inter', sans-serif;
    font-size: 0.8125rem;
    font-weight: 600;
    letter-spacing: 0.04em;
    font-variant-numeric: tabular-nums;
    padding: 0.0625rem 0.5rem;
    border-radius: 9999px;
    color: color-mix(in srgb, var(--faq-color) 92%, transparent);
    background: color-mix(in srgb, var(--faq-color) 10%, transparent);
    border: 1px solid color-mix(in srgb, var(--faq-color) 22%, transparent);
}

/*
 * The accent is inherited from the enclosing .faq-group, so every row in a
 * section agrees and the colour carries meaning. Stagger runs per row WITHIN
 * its group, on top of the group's own delay.
 */
.faq-item {
    position: relative;
    border-radius: 0.75rem;
    overflow: hidden;
    cursor: pointer;
    background: linear-gradient(160deg, rgba(18, 13, 6, 0.75) 0%, rgba(10, 7, 3, 0.85) 100%);
    border: 1px solid rgba(212, 175, 55, 0.12);
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.02);
    transition: background 0.25s ease,
                border-color 0.25s ease,
                box-shadow 0.25s ease;

    opacity: 0;
    transform: translateY(10px);
    animation: faqItemIn 0.25s ease forwards;
    animation-delay: calc(var(--stagger, 0) * 40ms);
}
@keyframes faqItemIn {
    to { opacity: 1; transform: translateY(0); }
}

/* Open state: pull in the per-item gold accent. */
.faq-item.is-open {
    background: linear-gradient(135deg,
        color-mix(in srgb, var(--faq-color) 9%, transparent) 0%,
        rgba(14, 10, 5, 0.92) 60%);
    border-color: color-mix(in srgb, var(--faq-color) 38%, transparent);
    box-shadow: 0 6px 28px rgba(0, 0, 0, 0.45),
                0 0 18px color-mix(in srgb, var(--faq-color) 8%, transparent);
}

/* Shimmer line under the top edge — fades in on open. */
.faq-shimmer {
    display: block;
    height: 1px;
    background: linear-gradient(90deg,
        transparent,
        color-mix(in srgb, var(--faq-color) 40%, transparent) 30%,
        color-mix(in srgb, var(--faq-color) 40%, transparent) 70%,
        transparent);
    opacity: 0;
    transition: opacity 0.25s ease;
}
.faq-item.is-open .faq-shimmer { opacity: 1; }

/* ─── Header row ─────────────────────────────────────────────────────────── */
.faq-header {
    width: 100%;
    display: flex;
    align-items: center;
    gap: 0.875rem;
    padding: 0.875rem 1.125rem;
    background: transparent;
    border: 0;
    cursor: pointer;
    text-align: right;
    color: inherit;
}

.faq-badge {
    flex-shrink: 0;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2rem;
    height: 2rem;
    border-radius: 0.5rem;
    color: color-mix(in srgb, var(--faq-color) 53%, transparent);
    background: color-mix(in srgb, var(--faq-color) 7%, transparent);
    border: 1px solid color-mix(in srgb, var(--faq-color) 16%, transparent);
    transition: transform 0.22s cubic-bezier(0.34, 1.56, 0.64, 1),
                background 0.22s ease,
                border-color 0.22s ease,
                box-shadow 0.22s ease,
                color 0.22s ease;
}
.faq-item.is-open .faq-badge {
    background: color-mix(in srgb, var(--faq-color) 13%, transparent);
    border-color: color-mix(in srgb, var(--faq-color) 33%, transparent);
    box-shadow: 0 0 14px color-mix(in srgb, var(--faq-color) 15%, transparent);
    color: var(--faq-color);
    transform: scale(1.08);
}

/* A question is a sentence, so it is set in the body face at reading weight
   and near-white. Measured 15.9:1 against the composited panel, against 6.83:1
   for the gold Cinzel it replaces. */
.faq-q {
    flex: 1 1 auto;
    min-width: 0;
    font-family: 'Inter', sans-serif;
    font-size: 1.0625rem;
    font-weight: 500;
    line-height: 1.5;
    color: #F0E6D2;
    transition: color 0.22s ease;
}
.faq-item.is-open .faq-q { color: #FFF8E7; font-weight: 600; }

.faq-chev {
    flex-shrink: 0;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 1.25rem;
    height: 1.25rem;
    border-radius: 0.375rem;
    background: rgba(212, 175, 55, 0.08);
    border: 1px solid rgba(212, 175, 55, 0.15);
    color: rgba(212, 175, 55, 0.85);
    transition: transform 0.25s cubic-bezier(0.34, 1.56, 0.64, 1),
                color 0.25s ease;
}
.faq-item.is-open .faq-chev {
    transform: rotate(180deg);
    color: var(--faq-color);
}

/* ─── Answer — grid-template-rows accordion ──────────────────────────────── */
/*
 * Classic modern trick: animate `grid-template-rows: 0fr → 1fr` and child
 * `min-height: 0; overflow: hidden`. This gives a smooth expand-to-
 * natural-content-height transition without any JS measuring.
 */
.faq-answer {
    display: grid;
    grid-template-rows: 0fr;
    transition: grid-template-rows 0.25s cubic-bezier(0.22, 1, 0.36, 1);
}
.faq-item.is-open .faq-answer {
    grid-template-rows: 1fr;
}
.faq-answer-inner {
    min-height: 0;
    overflow: hidden;
}
.faq-answer-inner > .faq-divider {
    display: block;
    height: 1px;
    margin: 0 1.125rem 0.75rem;
    background: linear-gradient(90deg,
        color-mix(in srgb, var(--faq-color) 30%, transparent),
        rgba(212, 175, 55, 0.1) 60%,
        transparent);
    /* Slight delay so the divider doesn't appear before the expand starts. */
    opacity: 0;
    transition: opacity 0.18s ease 0.08s;
}
.faq-item.is-open .faq-answer-inner > .faq-divider { opacity: 1; }

/* Indented to the question's left edge (badge 2rem + the header's 0.875rem
   gap + its 1.125rem padding), and capped at a reading measure so an answer
   does not run the full width of a 76rem panel. */
.faq-answer-inner > p {
    margin: 0 1.125rem 1.125rem;
    /* NOT ch: measured, 74ch of Inter at 14.4px is 672px, which is 101 real
       characters per line - ch is the width of "0", not of average text.
       36rem measures 518px, about 78 characters. */
    max-width: 36rem;
    font-family: 'Inter', sans-serif;
    font-size: 0.875rem;
    line-height: 1.75;
    /* colour is set by the readability block at the foot of this file */
}
@media (min-width: 640px) {
    .faq-answer-inner > .faq-divider { margin-right: 4rem; }
    .faq-answer-inner > p            { margin-right: 4rem; }
}

/* ─── Reduced-motion safety ──────────────────────────────────────────────── */
@media (prefers-reduced-motion: reduce) {
    .faq-group,
    .faq-item,
    .faq-answer,
    .faq-badge,
    .faq-chev,
    .faq-shimmer { animation: none !important; transition: none !important; }
    .faq-group,
    .faq-item { opacity: 1; transform: none; }
    .faq-item.is-open .faq-chev { transform: rotate(180deg); }
    .faq-item.is-open .faq-badge { transform: scale(1.05); }
}

/* ════════════════════════════════════════════════════════════════════════════
   PHASE 5 — Guides content (library + detail)
   ──────────────────────────────────────────────────────────────────────────── */

/*
 * Two-column layout: 200px library list (left) + flex guide-detail (right).
 * On narrow screens the library stacks above the detail. The detail panes
 * stack in a single grid cell (same overlay pattern as Tribes / Buildings).
 */
.guides-pane {
    /* The .manual-modal-content already has overflow-y: auto, but the V0
       design has the LIBRARY scroll independently from the DETAIL. We keep
       the modal scroll for the page-level fallback. */
    height: auto;
}

/* ════════════════════════════════════════════════════════════════════════════
   GUIDES — header command bar + drop-down library
   ──────────────────────────────────────────────────────────────────────────
   The library was a permanent 220px sidebar. Measured at 1440px it left the
   guide being read with 628px inside a 922px dialog, and spent ~185px of its
   own 648px column on a title block, a search field and 7 filter chips that
   wrapped onto three rows - all before the first guide appeared.

   Search, filters and the library opener now live in the modal header, and the
   list itself became a sheet that drops over the reading area only when asked
   for. The reading pane gets the full width at all times.
   ════════════════════════════════════════════════════════════════════════════ */

.guides-pane {
    position: relative;      /* anchor for the absolutely-positioned sheet */
    height: 100%;
    min-height: 0;
}

/* ─── Header command bar ─────────────────────────────────────────────────── */
.manual-toolbar {
    display: flex;
    align-items: center;
    gap: 0.625rem;
    margin-top: 0.75rem;
    min-width: 0;
}
/* One copy of the chips shows at a time - toolbar on desktop, sheet on mobile. */
.guides-chips.in-sheet { display: none; }
@media (max-width: 767px) {
    /*
     * Phone: the toolbar keeps ONE row - search plus the library opener. Letting
     * all three controls wrap made the header 206px on a 500px screen, a quarter
     * of the dialog spent on chrome. The filter chips move into the sheet, which
     * is the only place they are useful anyway.
     */
    .guides-chips.in-toolbar { display: none; }
    .guides-chips.in-sheet   { display: flex; margin-bottom: 0.75rem; }
    .guides-search  { flex: 1 1 auto; }
    .guides-browse  { max-width: none; flex: 1 1 11rem; }
}

/* ─── Library button ─────────────────────────────────────────────────────── */
.guide-pick {
    --guide-color: #D4AF37;
    position: relative;
    width: 100%;
    text-align: right;
    border-radius: 0.75rem;
    overflow: hidden;
    cursor: pointer;
    padding: 0;
    background: linear-gradient(160deg, rgba(18, 13, 6, 0.75) 0%, rgba(10, 7, 3, 0.85) 100%);
    border: 1px solid rgba(212, 175, 55, 0.08);
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.02);
    transition: transform 0.25s cubic-bezier(0.34, 1.56, 0.64, 1),
                background 0.25s ease,
                border-color 0.25s ease,
                box-shadow 0.25s ease,
                opacity 0.25s ease,
                filter 0.25s ease;
}
.guide-pick:hover {
    transform: scale(1.03) translateY(-1px);
}

/* :has() lets us dim non-hovered, non-active siblings when one is hovered. */
.guides-list:has(.guide-pick:hover) .guide-pick:not(:hover):not(.is-active) {
    opacity: 0.3;
    transform: scale(0.97);
    filter: grayscale(0.4);
}

.guide-pick.is-active {
    background: linear-gradient(135deg,
        color-mix(in srgb, var(--guide-color) 9%, transparent) 0%,
        rgba(212, 175, 55, 0.08) 50%,
        rgba(10, 7, 3, 0.9) 100%);
    border-color: color-mix(in srgb, var(--guide-color) 33%, transparent);
    box-shadow: 0 4px 24px color-mix(in srgb, var(--guide-color) 12%, transparent),
                0 0 0 1px color-mix(in srgb, var(--guide-color) 7%, transparent),
                inset 0 1px 0 rgba(255, 255, 255, 0.05);
}
.guide-pick.is-active:hover {
    transform: scale(1.01);
}

/* Top shimmer only when active. */
.guide-pick-shimmer {
    position: absolute;
    inset-inline: 0;
    top: 0;
    height: 1px;
    pointer-events: none;
    opacity: 0;
    background: linear-gradient(90deg,
        transparent,
        color-mix(in srgb, var(--guide-color) 53%, transparent) 40%,
        color-mix(in srgb, var(--guide-color) 53%, transparent) 60%,
        transparent);
    transition: opacity 0.25s ease;
}
.guide-pick.is-active .guide-pick-shimmer { opacity: 1; }

/* Left accent bar — slides in on active. */
.guide-pick-accent-bar {
    position: absolute;
    right: 0;
    top: 0.75rem;
    bottom: 0.75rem;
    width: 3px;
    border-radius: 9999px;
    background: linear-gradient(180deg, var(--guide-color) 0%, color-mix(in srgb, var(--guide-color) 38%, transparent) 100%);
    transform: scaleY(0);
    transform-origin: center;
    opacity: 0;
    transition: transform 0.3s cubic-bezier(0.34, 1.56, 0.64, 1), opacity 0.25s ease;
}
.guide-pick.is-active .guide-pick-accent-bar {
    transform: scaleY(1);
    opacity: 1;
}

/* Right-edge glow orb — active only. */
.guide-pick-glow-orb {
    position: absolute;
    left: -1.5rem;
    top: 50%;
    transform: translateY(-50%);
    width: 5rem;
    height: 5rem;
    border-radius: 50%;
    pointer-events: none;
    background: radial-gradient(circle, color-mix(in srgb, var(--guide-color) 9%, transparent) 0%, transparent 70%);
    opacity: 0;
    transition: opacity 0.3s ease;
}
.guide-pick.is-active .guide-pick-glow-orb { opacity: 1; }

.guide-pick-body {
    position: relative;
    padding: 0.75rem 1.25rem 0.75rem 1rem;
}
.guide-pick-row {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    margin-bottom: 0.375rem;
}
.guide-pick-tag {
    font-family: 'Inter', sans-serif;
    font-size: 0.8125rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.2em;
    padding: 0.125rem 0.5rem;
    border-radius: 0.375rem;
    color: var(--guide-color);
    background: color-mix(in srgb, var(--guide-color) 6%, transparent);
    border: 1px solid color-mix(in srgb, var(--guide-color) 20%, transparent);
    transition: background 0.22s ease, border-color 0.22s ease, transform 0.22s ease, box-shadow 0.22s ease;
}
.guide-pick.is-active .guide-pick-tag {
    background: color-mix(in srgb, var(--guide-color) 13%, transparent);
    border-color: color-mix(in srgb, var(--guide-color) 40%, transparent);
    box-shadow: 0 0 10px color-mix(in srgb, var(--guide-color) 15%, transparent);
    transform: scale(1.05);
}
.guide-pick-count {
    font-family: 'Inter', sans-serif;
    font-size: 0.8125rem;
    padding: 0.0625rem 0.375rem;
    border-radius: 0.25rem;
    background: rgba(255, 255, 255, 0.04);
    color: rgba(154, 130, 85, 0.85);
}
.guide-pick-title {
    margin: 0;
    font-family: 'Cinzel', serif;
    font-size: 0.8125rem;
    font-weight: 700;
    line-height: 1.35;
    color: rgba(190, 170, 130, 0.85);
    transition: color 0.22s ease, text-shadow 0.22s ease;
}
.guide-pick.is-active .guide-pick-title {
    color: #FFF8E7;
    text-shadow: 0 0 20px color-mix(in srgb, var(--guide-color) 25%, transparent);
}
.guide-pick-subtitle {
    margin: 0.125rem 0 0;
    font-family: 'Inter', sans-serif;
    font-size: 0.8125rem;
    color: rgba(154, 130, 85, 0.85);
}
.guide-pick.is-active .guide-pick-subtitle { color: rgba(190, 170, 130, 0.85); }

/* ─── Reading pane ───────────────────────────────────────────────────────── */
/* All detail panes occupy the same grid cell so crossfading happens in-place. */
.guides-detail {
    display: grid;
    grid-template-columns: 1fr;
    grid-template-rows: auto;
    min-height: 0;
    /* Fills whatever height the dialog actually has and scrolls inside it. This
       replaces a `max-height: 72vh` guess that left ~45px of the available 90vh
       simply unused, and that would have drifted again the moment the header
       height changed. Nothing here is expressed in vh any more. */
    height: 100%;
    overflow-y: auto;
    overscroll-behavior: contain;
}
.guides-detail::-webkit-scrollbar { width: 7px; }
.guides-detail::-webkit-scrollbar-track { background: transparent; }
.guides-detail::-webkit-scrollbar-thumb { background: rgba(212, 175, 55, 0.22); border-radius: 4px; }
.guides-detail::-webkit-scrollbar-thumb:hover { background: rgba(212, 175, 55, 0.42); }

/*
 * ── READING MEASURE ──────────────────────────────────────────────────────────
 * Freeing the sidebar's 220px must NOT simply make the lines longer: measured
 * before this change the guide text already ran at ~77 characters per line, and
 * comfortable prose is 60-75. So the running text is capped and the extra width
 * goes to the elements that actually benefit from it - tables, figures, callouts
 * and the reward grid - which stay full-bleed.
 */
.guide-section-intro,
.guide-bullets li p {
    /*
     * ⚠ Deliberately NOT in `ch`. Inter's zero is 9.08px at this size while its
     * average lowercase letter is ~7.1px, so a `68ch` cap measured out at 618px
     * and 90 characters per line - it did nothing at all. Calibrated instead by
     * binary-searching the offset where real guide text wraps to a second line:
     *   618px -> 90 chars    518px -> 72    490px -> 69    461px -> 63
     * 34rem = 490px = ~69 characters. Re-measure if the body size changes.
     */
    max-width: 34rem;
}
.guide-detail-pane {
    --guide-color: #D4AF37;
    grid-column: 1 / -1;
    grid-row: 1;
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
}

.guide-pane-enter        { transition: opacity 0.32s cubic-bezier(0.22, 1, 0.36, 1),
                                       transform 0.32s cubic-bezier(0.22, 1, 0.36, 1); }
.guide-pane-enter-start  { opacity: 0; transform: translateX(-20px) scale(0.98); }
.guide-pane-enter-end    { opacity: 1; transform: translateX(0)    scale(1);    }
.guide-pane-leave        { transition: opacity 0.22s ease, transform 0.22s ease; }
.guide-pane-leave-start  { opacity: 1; transform: translateX(0)    scale(1);    }
.guide-pane-leave-end    { opacity: 0; transform: translateX(16px) scale(0.98); }

/* ─── Banner ─────────────────────────────────────────────────────────────── */
.guide-banner {
    position: relative;
    display: flex;
    align-items: stretch;
    border-radius: 0.75rem;
    overflow: hidden;
    background: linear-gradient(135deg,
        color-mix(in srgb, var(--guide-color) 6%, transparent) 0%,
        rgba(18, 13, 6, 0.85) 40%,
        rgba(10, 7, 3, 0.92) 100%);
    border: 1px solid color-mix(in srgb, var(--guide-color) 16%, transparent);
    box-shadow:
        0 6px 28px rgba(0, 0, 0, 0.45),
        0 0 0 1px color-mix(in srgb, var(--guide-color) 4%, transparent),
        inset 0 1px 0 rgba(255, 255, 255, 0.03);
}
.guide-banner-shimmer {
    position: absolute;
    inset-inline: 0;
    top: 0;
    height: 1px;
    pointer-events: none;
    background: linear-gradient(90deg,
        transparent,
        color-mix(in srgb, var(--guide-color) 33%, transparent) 30%,
        color-mix(in srgb, var(--guide-color) 33%, transparent) 70%,
        transparent);
}
.guide-banner-corner-glow {
    position: absolute;
    top: -2rem;
    left: -2rem;
    width: 6rem;
    height: 6rem;
    border-radius: 50%;
    pointer-events: none;
    background: radial-gradient(circle, color-mix(in srgb, var(--guide-color) 7%, transparent) 0%, transparent 60%);
}

/*
 * Banner image — clickable button that pops the full-size lightbox.
 * Zero default-button styling (no native bg/border), full-bleed image,
 * zoom-in cursor + zoom magnifier badge on hover make the interaction
 * discoverable without making the badge always-on (V0 had it always-on
 * which competes with the painterly art).
 */
.guide-banner-image {
    position: relative;
    width: 8rem;
    flex-shrink: 0;
    overflow: hidden;
    border-left: 1px solid color-mix(in srgb, var(--guide-color) 9%, transparent);
    padding: 0;
    background: transparent;
    border-top: 0;
    border-bottom: 0;
    border-right: 0;
    cursor: zoom-in;
    color: inherit;
}
.guide-banner-image img {
    width: 100%;
    height: 100%;
    min-height: 6.25rem;
    object-fit: cover;
    object-position: top;
    transition: transform 0.3s ease;
    display: block;
}
.guide-banner-image:hover img {
    transform: scale(1.05);
}
.guide-banner-fade {
    position: absolute;
    inset: 0;
    pointer-events: none;
}
.guide-banner-fade.right  { background: linear-gradient(90deg, transparent 50%, rgba(10, 7, 3, 0.95) 100%); }
.guide-banner-fade.bottom { background: linear-gradient(180deg, transparent 40%, rgba(10, 7, 3, 0.7) 100%); }
.guide-banner-preview-label {
    position: absolute;
    bottom: 0.375rem;
    right: 0.375rem;
    padding: 0.0625rem 0.375rem;
    border-radius: 0.25rem;
    font-family: 'Cinzel', serif;
    font-size: 0.8125rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--guide-color);
    background: rgba(0, 0, 0, 0.7);
    border: 1px solid color-mix(in srgb, var(--guide-color) 25%, transparent);
    opacity: 0;
    transition: opacity 0.2s ease;
}
.guide-banner-image:hover .guide-banner-preview-label { opacity: 1; }

/* Magnifier badge — appears centered on hover. */
.guide-banner-zoom-badge {
    position: absolute;
    top: 50%;
    right: 50%;
    width: 2.25rem;
    height: 2.25rem;
    border-radius: 50%;
    transform: translate(50%, -50%) scale(0.6);
    background: color-mix(in srgb, var(--guide-color) 22%, rgba(0, 0, 0, 0.65));
    border: 1px solid color-mix(in srgb, var(--guide-color) 55%, transparent);
    box-shadow: 0 0 16px color-mix(in srgb, var(--guide-color) 25%, transparent);
    color: #FFF8E7;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.2s ease, transform 0.2s cubic-bezier(0.34, 1.56, 0.64, 1);
}
.guide-banner-zoom-badge svg {
    width: 1.125rem;
    height: 1.125rem;
}
.guide-banner-image:hover .guide-banner-zoom-badge {
    opacity: 1;
    transform: translate(50%, -50%) scale(1);
}

.guide-banner-text {
    position: relative;
    z-index: 1;
    display: flex;
    flex-direction: column;
    justify-content: center;
    flex: 1 1 auto;
    min-width: 0;
    padding: 0.875rem 1.25rem;
    gap: 0.375rem;
}
.guide-banner-row {
    display: flex;
    align-items: center;
    gap: 0.5rem;
}
.guide-banner-tag {
    font-family: 'Inter', sans-serif;
    font-size: 0.875rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.22em;
    padding: 0.1875rem 0.5rem;
    border-radius: 0.375rem;
    color: var(--guide-color);
    background: color-mix(in srgb, var(--guide-color) 9%, transparent);
    border: 1px solid color-mix(in srgb, var(--guide-color) 27%, transparent);
    box-shadow: 0 0 12px color-mix(in srgb, var(--guide-color) 9%, transparent);
}
.guide-banner-pos {
    font-family: 'Inter', sans-serif;
    font-size: 0.875rem;
    padding: 0.0625rem 0.375rem;
    border-radius: 0.25rem;
    background: rgba(255, 255, 255, 0.04);
    color: rgba(154, 130, 85, 0.85);
}

.guide-banner-title {
    margin: 0.125rem 0 0;
    font-family: 'Cinzel', serif;
    font-size: 1.25rem;
    font-weight: 700;
    letter-spacing: 0.05em;
    background: linear-gradient(180deg, #FFF8E7 0%, #F4E287 45%, var(--guide-color) 100%);
    -webkit-background-clip: text;
    background-clip: text;
    -webkit-text-fill-color: transparent;
    color: transparent;
}
.guide-banner-subtitle {
    margin: 0;
    font-family: 'Inter', sans-serif;
    font-size: 0.8125rem;
    color: rgba(190, 170, 130, 0.85);
}

.guide-banner-stats {
    display: flex;
    align-items: center;
    gap: 0.625rem;
    margin-top: 0.125rem;
}
.guide-banner-stats > span {
    display: inline-flex;
    align-items: center;
    gap: 0.25rem;
    font-family: 'Inter', sans-serif;
    font-size: 0.8125rem;
    color: rgba(154, 130, 85, 0.85);
}
.stat-dot {
    width: 6px;
    height: 6px;
    border-radius: 50%;
}
.stat-dot-gold { background: rgba(212, 175, 55, 0.45); }

/* ─── Section cards ──────────────────────────────────────────────────────── */
.guide-sections {
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
}

.guide-section {
    position: relative;
    border-radius: 0.75rem;
    overflow: hidden;
    background: linear-gradient(160deg, rgba(18, 13, 6, 0.8) 0%, rgba(10, 7, 3, 0.88) 100%);
    border: 1px solid rgba(212, 175, 55, 0.1);
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.02);
    transition: transform 0.25s ease, border-color 0.25s ease, box-shadow 0.25s ease, opacity 0.25s ease;
}
/*
 * ⚠ Lifts, does NOT scale. `transform: scale(1.01)` grew a 1035px-wide section by
 * ~10px, i.e. ~5px past each edge - and .guides-detail is a scroll container, so
 * per spec its overflow-x resolves to `auto` and it clipped the overhang. The right
 * edge was protected by padding-right, the left was not, so a hovered section looked
 * sliced against an invisible wall on its left. Translating on Y changes no width,
 * so it cannot clip sideways, and it does not resample the text the way a fractional
 * scale does.
 */
.guide-section:hover {
    transform: translateY(-2px);
    border-color: color-mix(in srgb, var(--guide-color) 21%, transparent);
    box-shadow: 0 8px 32px rgba(0, 0, 0, 0.4),
                0 0 20px color-mix(in srgb, var(--guide-color) 7%, transparent),
                inset 0 1px 0 rgba(255, 255, 255, 0.04);
}
/* Dim sibling sections on hover. */
.guide-sections:has(.guide-section:hover) .guide-section:not(:hover) {
    opacity: 0.5;
}

.guide-section-shimmer {
    position: absolute;
    inset-inline: 0;
    top: 0;
    height: 1px;
    pointer-events: none;
    opacity: 0;
    background: linear-gradient(90deg,
        transparent,
        color-mix(in srgb, var(--guide-color) 33%, transparent) 40%,
        color-mix(in srgb, var(--guide-color) 33%, transparent) 60%,
        transparent);
    transition: opacity 0.22s ease;
}
.guide-section:hover .guide-section-shimmer { opacity: 1; }

.guide-section-head {
    display: flex;
    align-items: center;
    gap: 0.625rem;
    padding: 0.5rem 1rem;
    background: linear-gradient(135deg,
        rgba(212, 175, 55, 0.06) 0%,
        rgba(212, 175, 55, 0.015) 60%,
        transparent 100%);
    border-bottom: 1px solid rgba(212, 175, 55, 0.06);
    transition: background 0.22s ease;
}
.guide-section:hover .guide-section-head {
    background: linear-gradient(135deg,
        color-mix(in srgb, var(--guide-color) 6%, transparent) 0%,
        rgba(212, 175, 55, 0.03) 60%,
        transparent 100%);
}

.guide-section-num {
    flex-shrink: 0;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 1.5rem;
    height: 1.5rem;
    border-radius: 0.25rem;
    font-family: 'Cinzel', serif;
    font-size: 0.875rem;
    font-weight: 700;
    background: rgba(212, 175, 55, 0.06);
    border: 1px solid rgba(212, 175, 55, 0.12);
    color: rgba(212, 175, 55, 0.85);
    transition: transform 0.22s cubic-bezier(0.34, 1.56, 0.64, 1),
                background 0.22s ease,
                border-color 0.22s ease,
                box-shadow 0.22s ease,
                color 0.22s ease;
}
.guide-section:hover .guide-section-num {
    transform: scale(1.08);
    background: color-mix(in srgb, var(--guide-color) 9%, transparent);
    border-color: color-mix(in srgb, var(--guide-color) 25%, transparent);
    box-shadow: 0 0 10px color-mix(in srgb, var(--guide-color) 9%, transparent);
    color: var(--guide-color);
}

.guide-section-title {
    margin: 0;
    font-family: 'Cinzel', serif;
    font-size: 0.8125rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.18em;
    color: #D4AF37;
    transition: color 0.22s ease, text-shadow 0.22s ease;
}
.guide-section:hover .guide-section-title {
    color: #F4E287;
    text-shadow: 0 0 12px color-mix(in srgb, var(--guide-color) 15%, transparent);
}

/* Section body */
.guide-section-body {
    padding: 0.75rem 1rem 0.875rem;
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}
.guide-section-intro {
    margin: 0 1.75rem 0 0;
    font-family: 'Inter', sans-serif;
    font-size: 0.875rem;
    line-height: 1.55;
    color: rgba(190, 170, 130, 0.75);
}

.guide-bullets {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 0.375rem;
}
.guide-bullets li {
    display: flex;
    align-items: flex-start;
    gap: 0.5rem;
    padding-right: 1.75rem;
}
.guide-bullets .dot {
    flex-shrink: 0;
    width: 6px;
    height: 6px;
    margin-top: 0.5rem;
    border-radius: 50%;
    background: linear-gradient(135deg, var(--guide-color) 0%, color-mix(in srgb, var(--guide-color) 38%, transparent) 100%);
    box-shadow: 0 0 6px color-mix(in srgb, var(--guide-color) 15%, transparent);
}
.guide-bullets li p {
    margin: 0;
    font-family: 'Inter', sans-serif;
    font-size: 0.875rem;
    line-height: 1.55;
    color: rgba(190, 170, 130, 0.75);
}
.guide-bullets li p strong {
    color: var(--guide-color);
    font-weight: 700;
}

/* Animated bottom bar on hover. */
.guide-section-bar {
    display: block;
    height: 1px;
    margin: 0 1rem 0.5rem;
    border-radius: 9999px;
    background: linear-gradient(90deg,
        transparent,
        color-mix(in srgb, var(--guide-color) 15%, transparent) 30%,
        color-mix(in srgb, var(--guide-color) 15%, transparent) 70%,
        transparent);
    transform: scaleX(0);
    transform-origin: center;
    transition: transform 0.22s ease;
}
.guide-section:hover .guide-section-bar { transform: scaleX(1); }

/* ─── Reduced-motion safety ──────────────────────────────────────────────── */
@media (prefers-reduced-motion: reduce) {
    .guide-pick,
    .guide-detail-pane,
    .guide-section,
    .guide-section-num,
    .guide-section-bar,
    .guide-banner-image img { transition: none !important; }
    .guide-pane-enter,
    .guide-pane-leave { transition: opacity 0.18s ease !important; }
    .guide-pane-enter-start,
    .guide-pane-leave-end { transform: none !important; }
    .guide-pane-enter-end,
    .guide-pane-leave-start { transform: none !important; }
}

/* ════════════════════════════════════════════════════════════════════════════
   LIGHTBOX — full-size guide preview overlay
   ──────────────────────────────────────────────────────────────────────────── */

.manual-lightbox {
    --lb-color: #D4AF37;
    position: fixed;
    inset: 0;
    /* Stacks above the manual modal (z-index 200) so the lightbox wins. */
    z-index: 300;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 1rem;
}

.manual-lightbox-backdrop {
    position: absolute;
    inset: 0;
    background: rgba(0, 0, 0, 0.82);
    backdrop-filter: blur(12px);
    -webkit-backdrop-filter: blur(12px);
}

.manual-lightbox-frame {
    position: relative;
    z-index: 1;
    margin: 0;
    max-width: 90vw;
    max-height: 88vh;
    display: flex;
    flex-direction: column;
    border-radius: 1rem;
    overflow: hidden;
    background: linear-gradient(160deg, rgba(22, 16, 10, 0.97) 0%, rgba(12, 9, 6, 0.99) 100%);
    border: 1px solid color-mix(in srgb, var(--lb-color) 38%, transparent);
    box-shadow:
        0 40px 100px rgba(0, 0, 0, 0.8),
        0 0 0 1px color-mix(in srgb, var(--lb-color) 6%, transparent),
        0 0 60px color-mix(in srgb, var(--lb-color) 18%, transparent),
        inset 0 1px 0 color-mix(in srgb, var(--lb-color) 16%, transparent);
}

/* Enter/leave transitions. */
.manual-lightbox-enter        { transition: opacity 0.28s cubic-bezier(0.22, 1, 0.36, 1),
                                            transform 0.28s cubic-bezier(0.22, 1, 0.36, 1); }
.manual-lightbox-enter-start  { opacity: 0; transform: scale(0.92); }
.manual-lightbox-enter-end    { opacity: 1; transform: scale(1);    }
.manual-lightbox-leave        { transition: opacity 0.18s ease, transform 0.18s ease; }
.manual-lightbox-leave-start  { opacity: 1; transform: scale(1);    }
.manual-lightbox-leave-end    { opacity: 0; transform: scale(0.96); }

/* Gold shimmer top bar — same visual language as the manual modal. */
.manual-lightbox-shimmer {
    position: absolute;
    inset-inline: 0;
    top: 0;
    height: 2px;
    pointer-events: none;
    background: linear-gradient(90deg,
        transparent 0%,
        color-mix(in srgb, var(--lb-color) 80%, transparent) 20%,
        #FFF8DC 50%,
        color-mix(in srgb, var(--lb-color) 80%, transparent) 80%,
        transparent 100%);
    box-shadow: 0 0 24px color-mix(in srgb, var(--lb-color) 50%, transparent);
}

/* Close button — red accent, mirrors the manual-modal-close. */
.manual-lightbox-close {
    position: absolute;
    top: 0.75rem;
    left: 0.75rem;
    z-index: 2;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2.25rem;
    height: 2.25rem;
    border-radius: 0.75rem;
    background: rgba(239, 68, 68, 0.18);
    border: 1px solid rgba(239, 68, 68, 0.45);
    color: rgba(239, 68, 68, 0.95);
    cursor: pointer;
    transition: transform 0.18s cubic-bezier(0.4, 0, 0.2, 1),
                background-color 0.18s ease,
                box-shadow 0.18s ease;
}
.manual-lightbox-close:hover {
    background: rgba(239, 68, 68, 0.28);
    box-shadow: 0 0 18px rgba(239, 68, 68, 0.35);
    transform: scale(1.1);
}
.manual-lightbox-close:active { transform: scale(0.88); }

.manual-lightbox-img {
    display: block;
    width: auto;
    height: auto;
    /* Subtract the caption row from max-height so the figure fits in 88vh. */
    max-width: 90vw;
    max-height: calc(88vh - 3rem);
    object-fit: contain;
    background: rgba(0, 0, 0, 0.5);
}

.manual-lightbox-cap {
    padding: 0.75rem 1rem;
    border-top: 1px solid color-mix(in srgb, var(--lb-color) 15%, transparent);
    background: rgba(0, 0, 0, 0.45);
    color: rgba(220, 200, 155, 0.78);
    font-family: 'Cinzel', serif;
    font-size: 0.8125rem;
    letter-spacing: 0.18em;
    text-transform: uppercase;
    text-align: center;
}

/* Reduced-motion safety. */
@media (prefers-reduced-motion: reduce) {
    .manual-lightbox-enter,
    .manual-lightbox-leave { transition: opacity 0.18s ease !important; }
    .manual-lightbox-enter-start,
    .manual-lightbox-leave-end { transform: none !important; }
    .manual-lightbox-enter-end,
    .manual-lightbox-leave-start { transform: none !important; }
}

/* ==========================================================================
   GUIDES v2 — search + topic filter chips + group dividers, callouts, tables,
   fallback banners, and the mobile focused reading pane.
   ========================================================================== */

/* ─── Library search ──────────────────────────────────────────────────────── */
/* In the toolbar the search no longer stacks, so it takes a share of the row
   rather than the full sidebar width. */
.guides-search { position: relative; flex: 0 1 17rem; min-width: 9rem; }
.guides-search svg {
    position: absolute; right: 0.6rem; top: 50%; transform: translateY(-50%);
    width: 15px; height: 15px; color: #C9A227; pointer-events: none;
}
.guides-search input {
    width: 100%; box-sizing: border-box;
    background: rgba(10, 7, 3, 0.8);
    border: 1px solid rgba(212, 175, 55, 0.22);
    border-radius: 9px; color: #E5E7EB;
    font-family: 'Inter', sans-serif; font-size: 0.82rem;
    padding: 0.5rem 1.9rem 0.5rem 0.7rem; outline: none;
    transition: border-color 0.2s, box-shadow 0.2s;
}
.guides-search input::placeholder { color: #6B7280; }
.guides-search input:focus {
    border-color: rgba(212, 175, 55, 0.45);
    box-shadow: 0 0 0 3px rgba(212, 175, 55, 0.12);
}

/* ─── Topic filter chips ──────────────────────────────────────────────────── */
/* One row that scrolls sideways instead of wrapping onto three. In the sidebar
   the wrap cost 96px of vertical space; in the toolbar height is the scarce
   axis, so the chips give up wrapping and keep the bar one row tall. */
.guides-chips {
    display: flex;
    flex-wrap: nowrap;
    gap: 0.35rem;
    flex: 1 1 auto;
    min-width: 0;
    overflow-x: auto;
    scrollbar-width: none;
    -ms-overflow-style: none;
    padding-bottom: 1px;              /* keeps focus rings off the clip edge */
}
.guides-chips::-webkit-scrollbar { display: none; }
.guides-chip {
    --chip: #D4AF37;
    flex: 0 0 auto; white-space: nowrap;
    display: inline-flex; align-items: center; gap: 0.3rem;
    font-family: 'Inter', sans-serif; font-size: 0.8125rem; font-weight: 600; letter-spacing: 0.02em;
    color: #9CA3AF; background: rgba(255, 255, 255, 0.03);
    border: 1px solid rgba(212, 175, 55, 0.12);
    padding: 0.3rem 0.6rem; border-radius: 999px; cursor: pointer;
    min-height: 28px; transition: color 0.18s, border-color 0.18s, background 0.18s;
}
.guides-chip:hover { color: #E5E7EB; border-color: rgba(212, 175, 55, 0.28); }
.guides-chip-dot { width: 6px; height: 6px; border-radius: 50%; background: var(--chip); opacity: 0.75; }
.guides-chip.is-active {
    color: #0A0703; font-weight: 700; border-color: transparent;
    background: linear-gradient(90deg, #E6C347, #FFEE99);
}
.guides-chip.is-active .guides-chip-dot { display: none; }

/* ─── Library opener ──────────────────────────────────────────────────────── */
/* Also the "you are here" label: with no permanent list, this is the only thing
   telling you which of the 16 guides you are in. */
.guides-browse {
    flex: 0 0 auto;
    max-width: 17rem;
    display: inline-flex;
    align-items: center;
    gap: 0.55rem;
    padding: 0.35rem 0.6rem;
    border-radius: 0.6rem;
    background: rgba(10, 7, 3, 0.8);
    border: 1px solid rgba(212, 175, 55, 0.22);
    cursor: pointer;
    text-align: right;
    transition: border-color 0.2s, background 0.2s, box-shadow 0.2s;
}
.guides-browse:hover { border-color: rgba(212, 175, 55, 0.45); background: rgba(20, 14, 6, 0.9); }
.guides-browse.is-open {
    border-color: rgba(212, 175, 55, 0.55);
    box-shadow: 0 0 0 3px rgba(212, 175, 55, 0.12);
}
.guides-browse-icon {
    flex-shrink: 0;
    display: inline-flex; align-items: center; justify-content: center;
    width: 1.75rem; height: 1.75rem;
    border-radius: 0.45rem;
    background: linear-gradient(135deg, rgba(212, 175, 55, 0.15), rgba(212, 175, 55, 0.05));
    border: 1px solid rgba(212, 175, 55, 0.25);
    color: #D4AF37;
}
.guides-browse-text { min-width: 0; display: flex; flex-direction: column; line-height: 1.15; }
.guides-browse-eyebrow {
    font-family: 'Cinzel', serif; font-size: 0.8125rem; font-weight: 700;
    letter-spacing: 0.2em; text-transform: uppercase;
    color: rgba(212, 175, 55, 0.8);
}
.guides-browse-title {
    font-family: 'Inter', sans-serif; font-size: 0.875rem; font-weight: 600;
    color: #E8D9B0;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.guides-browse-chev {
    flex-shrink: 0; width: 15px; height: 15px; color: rgba(212, 175, 55, 0.8);
    transition: transform 0.25s cubic-bezier(0.22, 1, 0.36, 1);
}
.guides-browse.is-open .guides-browse-chev { transform: rotate(180deg); }

/* ─── The library sheet ───────────────────────────────────────────────────── */
/*
 * Absolutely positioned over the reading pane on purpose: opening the library
 * must not resize or reflow the guide underneath, so closing it again returns
 * you to the same scroll position and the same line.
 */
.manual-sheet {
    position: absolute;
    inset-inline: 0;
    top: 0;
    z-index: 30;
    max-height: 100%;
    overflow-y: auto;
    overscroll-behavior: contain;
    padding: 1rem;
    border-radius: 0.9rem;
    background: linear-gradient(170deg, rgba(24, 17, 9, 0.99) 0%, rgba(12, 9, 5, 0.995) 100%);
    border: 1px solid rgba(212, 175, 55, 0.3);
    box-shadow: 0 28px 70px rgba(0, 0, 0, 0.75), 0 0 0 1px rgba(212, 175, 55, 0.06);
}
.manual-sheet::-webkit-scrollbar { width: 7px; }
.manual-sheet::-webkit-scrollbar-track { background: transparent; }
.manual-sheet::-webkit-scrollbar-thumb { background: rgba(212, 175, 55, 0.22); border-radius: 4px; }

.manual-sheet-group + .manual-sheet-group { margin-top: 0.85rem; }

/* auto-fill rather than a fixed count, so the same rule gives 2 columns on a
   tablet and 4 on the wide shell without another breakpoint */
.manual-sheet-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr));
    gap: 0.5rem;
    align-items: start;
}

.manual-sheet-enter        { transition: opacity 0.22s ease, transform 0.28s cubic-bezier(0.22, 1, 0.36, 1); }
.manual-sheet-enter-start  { opacity: 0; transform: translateY(-0.75rem) scale(0.99); }
.manual-sheet-enter-end    { opacity: 1; transform: none; }
.manual-sheet-leave        { transition: opacity 0.16s ease, transform 0.16s ease; }
.manual-sheet-leave-start  { opacity: 1; transform: none; }
.manual-sheet-leave-end    { opacity: 0; transform: translateY(-0.5rem) scale(0.99); }
@media (prefers-reduced-motion: reduce) {
    .manual-sheet-enter, .manual-sheet-leave { transition: opacity 0.15s ease; }
    .manual-sheet-enter-start, .manual-sheet-leave-end { transform: none; }
}

/* ─── Group dividers in the list ──────────────────────────────────────────── */
.guides-group-label {
    font-family: 'Cinzel', serif; font-size: 0.8125rem; font-weight: 600;
    letter-spacing: 0.18em; text-transform: uppercase; color: #C9A227;
    display: flex; align-items: center; gap: 0.5rem;
    padding: 0.7rem 0.4rem 0.25rem;
}
.guides-group-label::after {
    content: ""; flex: 1; height: 1px;
    background: linear-gradient(90deg, rgba(212, 175, 55, 0.25), transparent);
}
.guides-group-label:first-child { padding-top: 0.2rem; }
.guides-empty { color: #9CA3AF; font-size: 0.9375rem; padding: 1rem 0.4rem; }

/* ─── Fallback banner (guides without an illustration yet) ────────────────── */
.guide-banner-image.is-fallback {
    display: flex; align-items: center; justify-content: center;
    background:
        radial-gradient(120% 140% at 15% 0%, color-mix(in srgb, var(--guide-color) 30%, transparent), transparent 60%),
        linear-gradient(135deg, color-mix(in srgb, var(--guide-color) 16%, #0E0A05), #0E0A05);
    cursor: default;
}
.guide-banner-fallback-icon {
    color: color-mix(in srgb, var(--guide-color) 80%, #ffffff);
    filter: drop-shadow(0 4px 12px rgba(0, 0, 0, 0.5));
    opacity: 0.92;
}

/* ─── Data tables inside a guide section ──────────────────────────────────── */
.guide-table-wrap {
    overflow-x: auto; margin: 0.85rem 0 0.25rem;
    border: 1px solid rgba(212, 175, 55, 0.22); border-radius: 10px;
    -webkit-overflow-scrolling: touch;
}
.guide-table { width: 100%; border-collapse: collapse; font-size: 0.8125rem; min-width: 420px; }
.guide-table thead th {
    background: rgba(212, 175, 55, 0.08); color: #F4E287;
    font-weight: 700; letter-spacing: 0.03em; text-transform: uppercase;
    font-size: 0.8125rem; text-align: right; padding: 0.5rem 0.7rem;
    border-bottom: 1px solid rgba(212, 175, 55, 0.22); white-space: nowrap;
}
.guide-table thead th.num,
.guide-table tbody td.num { text-align: center; font-variant-numeric: tabular-nums; }
.guide-table tbody td {
    padding: 0.45rem 0.7rem; color: #D1D5DB;
    border-bottom: 1px solid rgba(255, 255, 255, 0.05); white-space: nowrap;
}
/* Description columns (0-1) wrap; only the value columns (.num) stay on one
   line. Without this a long description forces the value columns off the
   panel instead of simply taking a second line. */
.guide-table tbody td:not(.num),
.guide-table thead th:not(.num) { white-space: normal; }
.guide-table tbody td:nth-child(2) { min-width: 12rem; }
.guide-table tbody tr:last-child td { border-bottom: none; }
.guide-table tbody td:first-child { font-weight: 600; color: #E5E7EB; }
.guide-table tbody td.num { color: #F4E287; font-weight: 600; }

/* ─── Callout boxes (warn / rule / tip) ───────────────────────────────────── */
.guide-callout {
    display: flex; gap: 0.65rem; align-items: flex-start;
    padding: 0.75rem 0.9rem; border-radius: 10px; margin: 0.9rem 0 0.25rem;
    border: 1px solid; font-size: 0.83rem; line-height: 1.55;
}
.guide-callout p { margin: 0; }
.guide-callout-icon { width: 17px; height: 17px; flex: none; margin-top: 1px; }
.guide-callout.is-warn { background: rgba(248, 113, 113, 0.08); border-color: rgba(248, 113, 113, 0.32); color: #fecaca; }
.guide-callout.is-warn .guide-callout-icon { color: #f87171; }
.guide-callout.is-rule { background: rgba(212, 175, 55, 0.08); border-color: rgba(212, 175, 55, 0.30); color: #f3e3b0; }
.guide-callout.is-rule .guide-callout-icon { color: #E6C347; }
.guide-callout.is-tip  { background: rgba(96, 165, 250, 0.08); border-color: rgba(96, 165, 250, 0.30); color: #cfe2fb; }
.guide-callout.is-tip  .guide-callout-icon { color: #60A5FA; }

/*
 * The mobile "library only, then swap to the reading pane" mechanism used to
 * live here (.guide-back plus the two .guides-grid/.is-reading rules). It is
 * gone: the sheet is the same control at every width, and the header's Browse
 * button is always on screen, so there is nothing to swap and nothing to go
 * "back" to.
 */

/* ─── Slim guide header (screenshots moved inline) ────────────────────────── */
.guide-banner {
    align-items: center !important;
    min-height: 0 !important;
    padding: 0.85rem 1.1rem !important;
    gap: 0.75rem;
}
.guide-banner-badge {
    display: inline-flex; align-items: center; justify-content: center;
    width: 2.1rem; height: 2.1rem; flex: none; border-radius: 9px;
    color: var(--guide-color);
    background: color-mix(in srgb, var(--guide-color) 13%, transparent);
    border: 1px solid color-mix(in srgb, var(--guide-color) 30%, transparent);
}
.guide-banner-text { padding: 0 !important; }

/* ─── Inline figures (full screenshots in context) ───────────────────────── */
.guide-figure { margin: 0.95rem 0 0.35rem; }
.guide-figure-btn {
    display: block; width: 100%; padding: 0; cursor: zoom-in; position: relative;
    background: #0b0805; border: 1px solid rgba(212, 175, 55, 0.25);
    border-radius: 10px; overflow: hidden;
    box-shadow: 0 6px 22px rgba(0, 0, 0, 0.45);
    transition: border-color 0.18s, box-shadow 0.18s;
}
.guide-figure-btn:hover { border-color: rgba(212, 175, 55, 0.5); box-shadow: 0 10px 30px rgba(0, 0, 0, 0.55); }
.guide-figure-btn img { display: block; width: 100%; height: auto; }
.guide-figure-zoom {
    position: absolute; top: 0.5rem; left: 0.5rem;
    width: 26px; height: 26px; display: inline-flex; align-items: center; justify-content: center;
    border-radius: 7px; color: #0A0703; background: rgba(212, 175, 55, 0.92);
    opacity: 0; transition: opacity 0.18s;
}
.guide-figure-btn:hover .guide-figure-zoom { opacity: 1; }
.guide-figure-zoom svg { width: 15px; height: 15px; }
.guide-figure-cap {
    margin-top: 0.45rem; font-size: 0.8125rem; color: #9CA3AF; font-style: italic;
    text-align: center; line-height: 1.45;
}

/* ==========================================================================
   READABILITY PASS — every guide/FAQ text +~1px and brighter (muted tans/grays
   at low opacity were getting swallowed by the dark background) + independent
   scrolling for the library list vs the reading pane.
   ========================================================================== */

/* ── Font sizes: +~1px (root is 14.4px, so +0.07rem ≈ +1px) ── */
/* Guides brought up to the same 12.6px floor as the other three tabs. */
.guides-search input            { font-size: 0.9375rem; }
.guides-chip                    { font-size: 0.875rem; color: #C7CBD2; }
.guides-group-label             { font-size: 0.875rem; }
.guide-pick-tag                 { font-size: 0.875rem; }
.guide-pick-count               { font-size: 0.875rem; }
.guide-pick-title               { font-size: 1rem; }
.guide-pick-subtitle            { font-size: 0.9375rem; }
.guide-banner-tag               { font-size: 0.875rem; }
.guide-banner-title             { font-size: 1.4rem; }
.guide-banner-subtitle          { font-size: 0.9375rem; }
.guide-section-title            { font-size: 1rem; }
.guide-section-intro            { font-size: 1rem; }
.guide-bullets li p             { font-size: 1rem; }
.guide-table                    { font-size: 0.9375rem; }
.guide-table thead th           { font-size: 0.875rem; }
.guide-callout                  { font-size: 0.9375rem; }
.guide-figure-cap               { font-size: 0.875rem; }
/*
 * FAQ sizes. The panel is a grouped accordion that scrolls by design - unlike the
 * tribes panel there is no fixed height budget to protect, so the type could
 * simply go up. The per-row category tag that used to live here is gone; the
 * group heading states it once.
 */
.faq-group-title                { font-size: 1rem; }        /* 14.4px */
.faq-q                          { font-size: 1.125rem; }    /* 16.2px */
.faq-answer-inner > p           { font-size: 1rem; }        /* 14.4px - matches the tribe/building body */

/* ── Brightness: lift the muted text so it reads clearly on the dark bg ── */
.guide-pick-subtitle                       { color: rgba(206, 196, 176, 0.85); }
.guide-pick.is-active .guide-pick-subtitle { color: rgba(230, 221, 202, 0.96); }
.guide-banner-subtitle                     { color: rgba(214, 202, 178, 0.9); }
.guide-section-intro                       { color: rgba(228, 220, 204, 0.97); }
.guide-bullets li p                        { color: rgba(230, 222, 206, 0.97); }
.guide-table tbody td                      { color: #E4E7EC; }
.guide-figure-cap                          { color: #BCC0C9; }
.faq-answer-inner > p                      { color: rgba(232, 223, 204, 0.96); }
.faq-q                                     { color: #F0E6D2; }   /* 15.50:1 */

/* The old two-column independent-scroll block lived here. There is only one
   scrolling pane now (.guides-detail), and it sizes itself from the dialog
   rather than from a vh fraction - see the reading-pane rules above. */
@media (min-width: 768px) {
    /* symmetric, so a hover glow has the same room to bloom on both sides of a
       section - the old right-only padding is what made the clipping one-sided */
    .guides-detail  { padding-inline: 0.5rem; }
}

/* ── Gentler hover "spotlight" — non-hovered items were dimming too hard.
      Left guide picks went to opacity 0.3 (+shrink +grayscale); soften to a
      light fade. Content sections too. ── */
.guides-list:has(.guide-pick:hover) .guide-pick:not(:hover):not(.is-active) {
    opacity: 0.72;
    transform: none;
    filter: grayscale(0.1);
}
.guide-sections:has(.guide-section:hover) .guide-section:not(:hover) {
    opacity: 0.82;
}

/* ── Smooth guide-to-guide swap ──────────────────────────────────────────────
   The reading pane fades out, the guide + its scroll position are swapped while
   it is invisible, then it fades back in — a clean crossfade with no visible
   scroll jump or transform "shuffle". Per-pane x-transitions were removed in
   favour of this single container fade. ── */
.guides-detail {
    transition: opacity 0.15s ease;
    will-change: opacity;
}
.guides-detail.is-swapping { opacity: 0; }
@media (prefers-reduced-motion: reduce) {
    .guides-detail { transition: none; }
}

/* ── First-10-Adventures rewards list (authentic in-game icons) ──────────────── */
.guide-rewards {
    list-style: none; margin: 0.95rem 0 0.3rem; padding: 0;
    display: flex; flex-direction: column; gap: 0.4rem;
}
.guide-reward {
    display: flex; align-items: center; gap: 0.7rem;
    padding: 0.5rem 0.7rem; border-radius: 10px;
    background: rgba(255, 255, 255, 0.025);
    border: 1px solid rgba(212, 175, 55, 0.1);
}
.guide-reward-num {
    flex: none; width: 1.55rem; height: 1.55rem;
    display: inline-flex; align-items: center; justify-content: center;
    border-radius: 7px; font-family: 'Cinzel', serif; font-weight: 700; font-size: 0.8125rem;
    color: var(--guide-color, #60A5FA);
    background: color-mix(in srgb, var(--guide-color, #60A5FA) 12%, transparent);
    border: 1px solid color-mix(in srgb, var(--guide-color, #60A5FA) 28%, transparent);
    font-variant-numeric: tabular-nums;
}
.guide-reward-icon {
    flex: none; width: 36px; height: 36px;
    display: inline-flex; align-items: center; justify-content: center;
    background: rgba(10, 7, 3, 0.5); border: 1px solid rgba(212, 175, 55, 0.14);
    border-radius: 8px;
}
.guide-reward-icon img { max-width: 27px; max-height: 27px; display: block; }
.guide-reward-main { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 0.05rem; }
.guide-reward-name { font-family: 'Inter', sans-serif; font-weight: 600; font-size: 0.92rem; color: #F0EADB; }
.guide-reward-desc { font-size: 0.8125rem; line-height: 1.35; color: rgba(216, 208, 192, 0.78); }
.guide-reward-amt { flex: none; display: flex; flex-direction: column; align-items: flex-end; gap: 0.2rem; }
.guide-reward-qty {
    font-family: 'Inter', sans-serif; font-weight: 700; font-size: 0.95rem;
    color: #F4E287; font-variant-numeric: tabular-nums; white-space: nowrap;
}
.guide-reward-speed {
    font-size: 0.8125rem; font-weight: 700; letter-spacing: 0.05em; text-transform: uppercase;
    color: #34D399; background: rgba(52, 211, 153, 0.12);
    border: 1px solid rgba(52, 211, 153, 0.3);
    padding: 0.1rem 0.42rem; border-radius: 999px; white-space: nowrap;
}

/* The buildings sheet packs 18 short tiles, so it wants a denser track than the
   guides sheet's 15rem cards. */
.manual-sheet-grid.is-compact { grid-template-columns: repeat(auto-fill, minmax(11.5rem, 1fr)); }

/* A toolbar holding a single control should not stretch it across the header. */
.manual-toolbar.is-single { justify-content: flex-start; }
.manual-toolbar.is-single .guides-browse { flex: 0 1 auto; }

/* ─── Guides: readable surfaces (owner, 2026-08-23) ───────────────────────
 * The guide cards sat on a near-black plate (rgba(18,13,6,.8) → rgba(10,7,3,.88),
 * 10% gold border) over the dark modal backdrop: surfaces 1.03-1.07 apart read
 * as no edge at all, and the text looked "uninviting". Same elevation the Play /
 * Server-details modal cards use: a warm brown plate, a 22% gold border and a
 * real drop shadow, with a visibly lit section head. Declared last so it wins. */
.guide-section {
    background: linear-gradient(165deg, rgba(44, 33, 20, 0.88) 0%, rgba(26, 19, 11, 0.92) 100%);
    border: 1px solid rgba(212, 175, 55, 0.22);
    box-shadow: 0 8px 28px rgba(0, 0, 0, 0.38), inset 0 1px 0 rgba(255, 255, 255, 0.05);
}
.guide-section-head {
    background: linear-gradient(135deg, rgba(212, 175, 55, 0.16) 0%, rgba(212, 175, 55, 0.06) 55%, rgba(212, 175, 55, 0.02) 100%);
    border-bottom: 1px solid rgba(212, 175, 55, 0.18);
}
.guide-section-body { padding: 0.9rem 1.1rem 1rem; }
.guide-section-intro, .guide-bullets li p { color: #EDE7D6; line-height: 1.62; }
.guide-banner {
    background: linear-gradient(135deg,
        color-mix(in srgb, var(--guide-color) 12%, transparent) 0%,
        rgba(44, 33, 20, 0.9) 40%,
        rgba(26, 19, 11, 0.94) 100%);
    border: 1px solid color-mix(in srgb, var(--guide-color) 28%, transparent);
}
.guide-table tbody td { color: #E3DCCB; }
.guide-table tbody tr:nth-child(even) td { background: rgba(255, 255, 255, 0.025); }
/* Second pass (owner): one step lighter still, and a wider measure (40rem ≈ 80
 * characters, the top of the readable range) so the text does not leave half of
 * each card empty. */
.guide-section {
    background: linear-gradient(165deg, rgba(56, 43, 26, 0.92) 0%, rgba(34, 25, 14, 0.94) 100%);
    border-color: rgba(212, 175, 55, 0.28);
}
.guide-section-intro, .guide-bullets li p { max-width: 40rem; }

/* ─── Same readable surfaces on the other three tabs (owner, 2026-08-23) ───
 * Tribes (.tribe-section), Buildings (.building-card-wrap) and FAQ (.faq-item)
 * used the same near-black plate as the guides did; they get the warm plate,
 * the 28% gold edge, a drop shadow and lighter ink. Declared last so it wins. */
.tribe-section,
.building-card-wrap,
.faq-item {
    background: linear-gradient(165deg, rgba(56, 43, 26, 0.92) 0%, rgba(34, 25, 14, 0.94) 100%);
    border: 1px solid rgba(212, 175, 55, 0.28);
    box-shadow: 0 8px 28px rgba(0, 0, 0, 0.38), inset 0 1px 0 rgba(255, 255, 255, 0.05);
}
.faq-item:hover, .faq-item.is-open {
    border-color: rgba(212, 175, 55, 0.42);
}
/* section-head strips (Description / Tribe advantages / Cost / tribe tables) */
.building-section-head, .tribe-section-head {
    color: #F4E287;
}
.building-top {
    background: linear-gradient(135deg, rgba(212, 175, 55, 0.14) 0%, rgba(212, 175, 55, 0.05) 55%, transparent 100%);
    border-bottom: 1px solid rgba(212, 175, 55, 0.18);
}
.building-desc, .building-tribe-line, .tribe-perks li span:last-child, .faq-answer-inner, .faq-answer-inner p {
    color: #EDE7D6;
    line-height: 1.62;
}
.building-tile {
    background: rgba(56, 43, 26, 0.55);
    border-color: rgba(212, 175, 55, 0.18);
}
.tribe-table td { color: #E3DCCB; }
.tribe-table tbody tr:nth-child(even) td { background: rgba(255, 255, 255, 0.025); }
.tribe-right {
    background: linear-gradient(165deg, rgba(56, 43, 26, 0.92) 0%, rgba(34, 25, 14, 0.94) 100%);
    border: 1px solid rgba(212, 175, 55, 0.28);
    box-shadow: 0 8px 28px rgba(0, 0, 0, 0.38), inset 0 1px 0 rgba(255, 255, 255, 0.05);
}
.tribe-table-head { color: #F4E287; }
.tribe-pick {
    background: linear-gradient(165deg, rgba(48, 37, 22, 0.9) 0%, rgba(30, 22, 12, 0.93) 100%);
    border-color: rgba(212, 175, 55, 0.2);
}

/* ════════════════════════════════════════════════════════════════════════════
   PHONES: THE WHOLE MANUAL FITS THE SCREEN  (2026-09-21, player report
   "Guide is not friendly on phone")
   ────────────────────────────────────────────────────────────────────────────
   Measured before this block, 360px and 412px, all 11 languages: on 4 of the 16
   guides the whole reading pane was up to 266px wider than the screen, so every
   paragraph was cut off at the right edge (the LEFT edge in Hebrew); on the
   other 12 the "available guides" button ran past the edge; the ten-column
   troop table could only be swiped sideways. After it: nothing is clipped and
   nothing needs a sideways swipe, in any language or guide.

   Kept LAST in the file on purpose: every rule here overrides a base rule, and
   a media query adds no specificity, so an override placed earlier loses.
   ════════════════════════════════════════════════════════════════════════════ */

/* A `1fr` track never shrinks below its widest unbreakable child, so a single
   data table (the quest rewards, 512px) set the width of the WHOLE reading pane.
   minmax(0, 1fr) pins the track to the dialog. Desktop is unaffected: there
   everything already fits. */
.guides-detail     { grid-template-columns: minmax(0, 1fr); }
.guide-detail-pane { min-width: 0; }

@media (max-width: 767px) {
    /* ── Guide tables: fit the phone, value cells may take a second line ── */
    .guide-table { min-width: 0; font-size: 0.75rem; }
    .guide-table thead th,
    .guide-table tbody td { padding: 0.4rem 0.45rem; }
    .guide-table thead th,
    .guide-table tbody td.num { white-space: normal; }
    .guide-table thead th { letter-spacing: 0; }
    .guide-table tbody td:nth-child(2) { min-width: 0; }

    /* Wider tables become one card per row (markup: .is-stack, td[data-label]).
       The first cell is the card title; every other cell sits beside its column
       name. start/end, not left/right, so the Hebrew twin needs no mirror. */
    .guide-table.is-stack thead { display: none; }
    .guide-table.is-stack,
    .guide-table.is-stack tbody,
    .guide-table.is-stack tr,
    .guide-table.is-stack td { display: block; width: 100%; }
    .guide-table.is-stack tbody tr {
        padding: 0.55rem 0.7rem;
        border-bottom: 1px solid rgba(212, 175, 55, 0.15);
    }
    .guide-table.is-stack tbody tr:last-child { border-bottom: none; }
    .guide-table.is-stack tbody td {
        display: flex;
        justify-content: space-between;
        align-items: baseline;
        gap: 0.75rem;
        padding: 0.12rem 0;
        border: 0;
        white-space: normal;
        text-align: end;
        font-size: 0.8125rem;
    }
    .guide-table.is-stack tbody td::before {
        content: attr(data-label);
        flex: 0 0 auto;
        max-width: 55%;
        text-align: start;
        color: rgba(212, 175, 55, 0.8);
        font-weight: 600;
    }
    .guide-table.is-stack tbody td:first-child {
        display: block;
        text-align: start;
        font-size: 0.875rem;
        padding-bottom: 0.25rem;
    }
    .guide-table.is-stack tbody td:first-child::before { content: none; }

    /* ── Toolbar: keeps its one row. The library button shows only the guide
       (or building) you are in; its count line is what pushed it off screen. ── */
    .guides-search { flex: 1 1 0; min-width: 6.5rem; }
    .guides-browse { flex: 0 1 auto; min-width: 0; max-width: 62%; }
    .guides-browse-text { overflow: hidden; }
    .guides-browse-eyebrow { display: none; }

    /* ── The "i" tip spans the header instead of centring on the small "i",
       which put it past the screen edge whenever the title was long. ── */
    .manual-modal-info { position: static; }
    .manual-modal-tip {
        left: 0.75rem;
        right: 0.75rem;
        width: auto;
        max-width: none;
        transform: none;
    }
    .manual-modal-tip::before { display: none; }

    /* ── Tribes: one card per unit instead of a ten-column table to swipe.
       Name first, then attack and both defences with the game's own icons, the
       four costs with the resource icons, then training time and speed. The
       768-900px step keeps the swipeable table defined above. ── */
    .tribe-table { min-width: 0; table-layout: auto; }
    .tribe-table colgroup,
    .tribe-table thead { display: none; }
    .tribe-table,
    .tribe-table tbody { display: block; width: 100%; }
    .tribe-table tbody tr {
        display: grid;
        grid-template-columns: repeat(12, minmax(0, 1fr));
        gap: 0.35rem 0.5rem;
        padding: 0.6rem 0.75rem;
    }
    .tribe-table td,
    .tribe-table td.unit {
        display: flex;
        align-items: center;
        gap: 0.35rem;
        min-width: 0;
        padding: 0;
        text-align: start;
        font-size: 0.8125rem;
    }
    .tribe-table td.unit { grid-column: 1 / -1; font-size: 0.875rem; font-weight: 600; overflow: visible; }
    .tribe-table td.unit .unit-icon { margin: 0; }
    .tribe-table td.unit > span { max-width: none; white-space: normal; overflow: visible; }
    .tribe-table td.atk,
    .tribe-table td.defi,
    .tribe-table td.defc { grid-column: span 4; }
    .tribe-table td.res  { grid-column: span 3; }
    .tribe-table td.time { grid-column: span 7; }
    .tribe-table td.spd  { grid-column: span 5; }
    .tribe-table td.atk::before,
    .tribe-table td.defi::before,
    .tribe-table td.defc::before,
    .tribe-table td.res::before {
        content: '';
        flex: 0 0 auto;
        width: 16px;
        height: 16px;
        background-repeat: no-repeat;
        filter: drop-shadow(0 0 2px rgba(0, 0, 0, 0.7));
    }
    .tribe-table td.atk::before  { background-image: url('/assets/img/manual/icons/att_all.gif'); }
    .tribe-table td.defi::before { background-image: url('/assets/img/manual/icons/def_i.gif'); }
    .tribe-table td.defc::before { background-image: url('/assets/img/manual/icons/def_c.gif'); }
    .tribe-table td.res::before  { width: 18px; height: 18px; background-image: url('/assets/img/manual/icons/res2.gif'); }
    .tribe-table td.res:nth-child(5)::before { background-position: 0 -1px; }    /* Lumber */
    .tribe-table td.res:nth-child(6)::before { background-position: 0 -26px; }   /* Clay   */
    .tribe-table td.res:nth-child(7)::before { background-position: 0 -53px; }   /* Iron   */
    .tribe-table td.res:nth-child(8)::before { background-position: 0 -77px; }   /* Crop   */
    .tribe-table td.time::before,
    .tribe-table td.spd::before {
        content: attr(data-label);
        color: rgba(212, 175, 55, 0.8);
        font-size: 0.75rem;
        font-weight: 600;
    }
}
