/* ==========================================================================
   Retail Empire — design system

   The look is "premium retail business intelligence", not accounting software and not
   sci-fi. Deep neutral ground, one warm accent for money and action, cool accents for
   the three constraints so the player learns them by colour before they learn them by
   name (GAME_DESIGN.md §5).
   ========================================================================== */

:root {
    /* Ground */
    --bg:            #0d1017;
    --bg-raised:     #141922;
    --bg-panel:      #181e29;
    --bg-inset:      #10141c;
    --bg-hover:      #1e2632;

    /* Lines */
    --line:          #232c3a;
    --line-strong:   #2f3a4c;

    /* Text */
    --text:          #e8ecf3;
    --text-muted:    #93a0b5;
    --text-dim:      #67728a;

    /* Brand: warm, commercial, money */
    --accent:        #e0a44c;
    --accent-hot:    #f0b866;
    --accent-dim:    #7a5a28;
    --accent-ghost:  rgba(224, 164, 76, 0.12);

    /* The three constraints — used consistently everywhere they appear */
    --demand:        #6aa9f5;   /* customers */
    --service:       #6ddaa8;   /* staff */
    --supply:        #c48ff0;   /* stock */

    /* Status */
    --positive:      #4ec98a;
    --negative:      #f2685f;
    --warning:       #e8b93f;

    --radius:        10px;
    --radius-sm:     6px;
    --shadow:        0 1px 2px rgba(0,0,0,.4), 0 8px 24px rgba(0,0,0,.28);

    --font: -apple-system, BlinkMacSystemFont, "Segoe UI", Inter, Roboto, "Helvetica Neue", Arial, sans-serif;
    --mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
}

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

/* min-height, not height: a fixed 100% pins the body box to the viewport while the content
   overflows past it, so anything measuring the document — a sticky offset, a full-height
   background, a screenshot — gets an answer that disagrees with what is on screen. */
html, body { min-height: 100%; }

body {
    margin: 0;
    background: var(--bg);
    /* A very slight warm lift from the top so the page does not read as flat black. */
    background-image: radial-gradient(1200px 500px at 50% -200px, rgba(224,164,76,.07), transparent 70%);
    color: var(--text);
    font: 15px/1.55 var(--font);
    -webkit-font-smoothing: antialiased;
}

a { color: var(--accent); text-decoration: none; }
a:hover { color: var(--accent-hot); text-decoration: underline; }

h1, h2, h3, h4 { margin: 0 0 .5rem; line-height: 1.25; font-weight: 650; letter-spacing: -.01em; }
h1 { font-size: 1.65rem; }
h2 { font-size: 1.2rem; }
h3 { font-size: 1rem; }
p  { margin: 0 0 1rem; }

.muted { color: var(--text-muted); }
.dim   { color: var(--text-dim); }
.mono  { font-family: var(--mono); font-variant-numeric: tabular-nums; }
.center { text-align: center; }
.nowrap { white-space: nowrap; }

/* --------------------------------------------------------------- brand mark */

.brand {
    display: inline-flex; align-items: center; gap: .6rem;
    font-weight: 700; letter-spacing: -.02em; font-size: 1.05rem;
    color: var(--text); text-decoration: none;
}
.brand:hover { text-decoration: none; color: var(--text); }
.brand__mark {
    width: 28px; height: 28px; flex: none;
    display: grid; place-items: center;
    border-radius: 7px;
    background: linear-gradient(150deg, var(--accent-hot), var(--accent-dim));
    color: #1a1206; font-weight: 800; font-size: .82rem;
}
.brand__text small {
    display: block; font-size: .62rem; font-weight: 600;
    letter-spacing: .14em; text-transform: uppercase; color: var(--text-dim);
}

/* --------------------------------------------------------------- layout: auth */

.auth-shell {
    min-height: 100%;
    display: grid;
    grid-template-columns: 1fr;
    align-content: start;
    justify-items: center;
    padding: 2.5rem 1.25rem 4rem;
}
.auth-card {
    width: 100%; max-width: 430px;
    background: var(--bg-panel);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    box-shadow: var(--shadow);
    padding: 1.75rem;
}
.auth-header { text-align: center; margin-bottom: 1.75rem; }
.auth-header .brand { margin-bottom: 1.5rem; }
.auth-header h1 { font-size: 1.35rem; }
.auth-header p { margin: 0; color: var(--text-muted); font-size: .9rem; }
.auth-footer {
    margin-top: 1.25rem; text-align: center;
    font-size: .88rem; color: var(--text-muted);
}

/* --------------------------------------------------------------- layout: app */

.app-header {
    position: sticky; top: 0; z-index: 30;
    background: rgba(13,16,23,.92);
    backdrop-filter: blur(10px);
    border-bottom: 1px solid var(--line);
}
.app-header__inner {
    max-width: 1240px; margin: 0 auto;
    padding: .7rem 1.25rem;
    display: flex; align-items: center; gap: 1.5rem;
}
.app-nav { display: flex; gap: .25rem; margin-left: auto; align-items: center; }
.app-signout { flex: none; margin-left: .25rem; }
.app-signout .btn--link { padding: .45rem .75rem; font-size: .9rem; }
.app-nav a {
    padding: .45rem .75rem; border-radius: var(--radius-sm);
    color: var(--text-muted); font-size: .9rem; font-weight: 500;
}
.app-nav a:hover { background: var(--bg-hover); color: var(--text); text-decoration: none; }
.app-nav a.is-active { background: var(--accent-ghost); color: var(--accent-hot); }
/* A button inside the nav is a button first: .app-nav a would otherwise win on
   specificity and mute the label to grey-on-amber. */
.app-nav a.btn--primary { color: #1a1206; }
.app-nav a.btn--primary:hover { background: var(--accent-hot); color: #1a1206; }

.app-main { max-width: 1240px; margin: 0 auto; padding: 1.75rem 1.25rem 4rem; }

.page-head {
    display: flex; align-items: flex-end; gap: 1rem;
    flex-wrap: wrap; margin-bottom: 1.5rem;
}
.page-head p { margin: .15rem 0 0; color: var(--text-muted); font-size: .92rem; }

/* --------------------------------------------------------------- panels */

.panel {
    background: var(--bg-panel);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    padding: 1.25rem;
}
.panel + .panel { margin-top: 1rem; }
/* Inside a grid the gap already handles spacing; the stacking margin would push every
   panel after the first out of alignment with its row. */
.grid > .panel + .panel { margin-top: 0; }
.panel__title {
    display: flex; align-items: center; gap: .5rem;
    font-size: .72rem; font-weight: 700; letter-spacing: .1em;
    text-transform: uppercase; color: var(--text-dim);
    margin-bottom: .9rem;
}

.grid { display: grid; gap: 1rem; }
@media (min-width: 760px)  { .grid--2 { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1000px) { .grid--3 { grid-template-columns: repeat(3, 1fr); } }

/* --------------------------------------------------------------- forms */

.field { margin-bottom: 1rem; }
.field > label {
    display: block; margin-bottom: .35rem;
    font-size: .82rem; font-weight: 600; color: var(--text-muted);
}
.field__hint { margin: .35rem 0 0; font-size: .78rem; color: var(--text-dim); }
.field__error { margin: .35rem 0 0; font-size: .8rem; color: var(--negative); }

.input {
    width: 100%; padding: .62rem .75rem;
    background: var(--bg-inset);
    border: 1px solid var(--line-strong);
    border-radius: var(--radius-sm);
    color: var(--text); font: inherit;
    transition: border-color .12s, box-shadow .12s;
}
.input:focus {
    outline: none;
    border-color: var(--accent);
    box-shadow: 0 0 0 3px var(--accent-ghost);
}
.input::placeholder { color: var(--text-dim); }
.input[aria-invalid="true"] { border-color: var(--negative); }

.checkbox {
    display: flex; align-items: flex-start; gap: .55rem;
    font-size: .87rem; color: var(--text-muted); cursor: pointer;
}
.checkbox input { margin-top: .2rem; accent-color: var(--accent); flex: none; }

.btn {
    display: inline-flex; align-items: center; justify-content: center; gap: .45rem;
    padding: .62rem 1.1rem;
    border: 1px solid transparent; border-radius: var(--radius-sm);
    font: inherit; font-weight: 600; cursor: pointer;
    transition: background .12s, border-color .12s, transform .06s;
}
.btn:hover { text-decoration: none; }
.btn:active { transform: translateY(1px); }

/* A disabled action has to LOOK disabled. An amber button that does nothing when
   clicked reads as a broken game, not as a rule. */
.btn:disabled,
.btn[disabled] {
    opacity: .38;
    cursor: not-allowed;
    filter: grayscale(.5);
}
.btn:disabled:active,
.btn[disabled]:active { transform: none; }
.btn--primary {
    background: var(--accent); color: #1a1206;
    border-color: var(--accent);
}
.btn--primary:hover { background: var(--accent-hot); color: #1a1206; }
.btn--ghost {
    background: transparent; color: var(--text-muted);
    border-color: var(--line-strong);
}
.btn--ghost:hover { background: var(--bg-hover); color: var(--text); }
.btn--block { width: 100%; }
.btn--link {
    background: none; border: none; padding: 0;
    color: var(--text-muted); font-size: .9rem; cursor: pointer;
}
.btn--link:hover { color: var(--text); text-decoration: underline; }

/* --------------------------------------------------------------- messages */

.alert {
    display: flex; gap: .65rem; align-items: flex-start;
    padding: .7rem .85rem; margin-bottom: 1rem;
    border: 1px solid; border-radius: var(--radius-sm);
    font-size: .88rem; line-height: 1.45;
}
.alert--error    { background: rgba(242,104,95,.09);  border-color: rgba(242,104,95,.35);  color: #ffb3ad; }
.alert--success  { background: rgba(78,201,138,.09);  border-color: rgba(78,201,138,.32);  color: #a2e6c2; }
.alert--info     { background: rgba(106,169,245,.09); border-color: rgba(106,169,245,.32); color: #b3d3fb; }
.alert__icon { flex: none; font-weight: 700; }
.alert a { color: inherit; text-decoration: underline; word-break: break-all; }

/* --------------------------------------------------------------- stat display */

.stat__label {
    font-size: .7rem; font-weight: 700; letter-spacing: .09em;
    text-transform: uppercase; color: var(--text-dim);
}
.stat__value {
    font-family: var(--mono); font-variant-numeric: tabular-nums;
    font-size: 1.5rem; font-weight: 650; letter-spacing: -.02em;
    margin-top: .15rem;
}
.stat__value--positive { color: var(--positive); }
.stat__value--negative { color: var(--negative); }

.badge {
    display: inline-flex; align-items: center; gap: .3rem;
    padding: .18rem .5rem; border-radius: 999px;
    font-size: .7rem; font-weight: 700; letter-spacing: .04em;
    text-transform: uppercase;
    background: var(--bg-hover); color: var(--text-muted);
    border: 1px solid var(--line-strong);
}
.badge--demand  { color: var(--demand);  border-color: rgba(106,169,245,.4); background: rgba(106,169,245,.1); }
.badge--service { color: var(--service); border-color: rgba(109,218,168,.4); background: rgba(109,218,168,.1); }
.badge--supply  { color: var(--supply);  border-color: rgba(196,143,240,.4); background: rgba(196,143,240,.1); }

/* --------------------------------------------------------------- empty state */

.empty {
    text-align: center; padding: 3rem 1.5rem;
    border: 1px dashed var(--line-strong); border-radius: var(--radius);
    background: var(--bg-inset);
}
.empty h2 { font-size: 1.1rem; }
.empty p { max-width: 46ch; margin: 0 auto 1.25rem; color: var(--text-muted); font-size: .92rem; }

/* --------------------------------------------------------------- landing */

.hero { max-width: 720px; margin: 0 auto; padding: 5rem 1.25rem 3rem; text-align: center; }
.hero h1 { font-size: clamp(1.9rem, 5vw, 2.7rem); margin-bottom: .85rem; }
.hero__lead { font-size: 1.05rem; color: var(--text-muted); margin-bottom: 2rem; }
.hero__actions { display: flex; gap: .75rem; justify-content: center; flex-wrap: wrap; }

.pillars {
    max-width: 980px; margin: 0 auto; padding: 0 1.25rem 5rem;
    display: grid; gap: 1rem;
}
@media (min-width: 820px) { .pillars { grid-template-columns: repeat(3, 1fr); } }
.pillar { padding: 1.25rem; border: 1px solid var(--line); border-radius: var(--radius); background: var(--bg-panel); }
.pillar h3 { font-size: .95rem; margin-bottom: .4rem; }
.pillar p { margin: 0; font-size: .88rem; color: var(--text-muted); }
.pillar__tag {
    font-size: .68rem; font-weight: 700; letter-spacing: .1em;
    text-transform: uppercase; margin-bottom: .6rem;
}

/* --------------------------------------------------------------- error page */

.error-page { max-width: 520px; margin: 0 auto; padding: 6rem 1.25rem; text-align: center; }
.error-page__code {
    font-family: var(--mono); font-size: 3.5rem; font-weight: 700;
    color: var(--line-strong); line-height: 1; margin-bottom: .75rem;
}

/* --------------------------------------------------------------- small screens

   Desktop-first is acceptable for the MVP, but the game is checked on a phone far more
   often than it is played on one — a player glances at the dashboard between other
   things. The header has to survive that. */

@media (max-width: 720px) {
    /* The header stacks: brand on one line, navigation on its own scrollable line beneath.
       Squeezing both onto one row pushed the last items off-screen entirely, which on a
       phone meant Finances and Sign out simply could not be reached. */
    .app-header__inner {
        padding: .55rem .9rem; gap: .5rem;
        flex-wrap: wrap; align-items: center;
    }
    .brand__text small { display: none; }          /* the tagline is not worth two lines */
    .brand__text { font-size: .95rem; white-space: nowrap; }

    /* Explicit order, because the source order puts navigation before sign-out and the
       wrapped layout wants the opposite: brand and sign-out share the first row, the
       scrolling navigation takes the second. */
    .app-header__inner > .brand { order: 1; }
    .app-signout            { order: 2; }
    .app-nav                { order: 3; }

    .app-nav {
        margin-left: 0; width: 100%;
        gap: .1rem; overflow-x: auto; scrollbar-width: none;
        -webkit-overflow-scrolling: touch;
        /* Bleed to the screen edges so the scroll affordance is obvious. */
        margin-inline: -.9rem; padding-inline: .9rem;
    }
    .app-nav::-webkit-scrollbar { display: none; }
    .app-nav a { padding: .35rem .6rem; font-size: .85rem; white-space: nowrap; flex: none; }

    /* Pinned to the brand row, top right, where it is always visible. */
    .app-signout { margin-left: auto; }
    .app-signout .btn--link { padding: .3rem 0; font-size: .82rem; }

    /* The sticky status bar sits under a header that is now two rows tall. */
    .statusbar { top: 90px; }

    .app-main { padding: 1.25rem .9rem 3rem; }
    .auth-shell { padding: 1.5rem .9rem 3rem; }
    .auth-card { padding: 1.25rem; }

    h1 { font-size: 1.4rem; }
    .empty { padding: 2rem 1rem; }
    .badge { white-space: normal; text-align: center; }

    /* Four headline stats read better two-up than stacked down the whole screen. */
    .grid--4 { grid-template-columns: repeat(2, 1fr); gap: .6rem; }
    .grid--4 .panel { padding: .8rem; }
    .grid--4 .stat__value { font-size: 1.2rem; }
}

/* --------------------------------------------------------------- dashboard

   The three constraints are drawn to a shared scale so the shortest bar is visibly the
   one that matters. Colour is consistent with the badges everywhere else in the game:
   blue demand, green service, purple supply. */

/* Ascending order matters: a later rule with an equal-specificity selector wins, so a
   min-width:620px block placed after min-width:900px would override it on wide screens. */
@media (min-width: 620px) { .grid--4 { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 900px) { .grid--4 { grid-template-columns: repeat(4, 1fr); } }
@media (min-width: 980px) { .grid--sidebar { grid-template-columns: minmax(0,1fr) 320px; align-items: start; } }

.stat__unit { font-size: .8rem; color: var(--text-dim); margin-left: .1rem; font-weight: 500; }
.stat__note { font-size: .75rem; margin-top: .2rem; }
.stat__note.negative { color: var(--negative); }

.store-head {
    display: flex; align-items: flex-start; justify-content: space-between;
    gap: 1rem; flex-wrap: wrap; margin-bottom: 1rem;
}
.store-head__revenue { font-size: 1.15rem; font-weight: 650; color: var(--accent); }

/* --- bottleneck indicator --- */

.bottleneck {
    border: 1px solid var(--line-strong);
    border-left-width: 3px;
    border-radius: var(--radius-sm);
    background: var(--bg-inset);
    padding: .85rem 1rem;
    margin-bottom: 1.25rem;
}
.bottleneck--demand  { border-left-color: var(--demand); }
.bottleneck--service { border-left-color: var(--service); }
.bottleneck--supply  { border-left-color: var(--supply); }

.bottleneck__head { display: flex; gap: .4rem; flex-wrap: wrap; margin-bottom: .5rem; }
.bottleneck__why  { margin: 0 0 .25rem; font-size: .9rem; font-weight: 550; }
.bottleneck__fix  { margin: 0; font-size: .85rem; color: var(--text-muted); }
.bottleneck__warn {
    margin: .6rem 0 0; padding-top: .6rem; font-size: .82rem;
    border-top: 1px solid var(--line); color: var(--warning);
}

/* --- constraint bars --- */

.constraints { display: grid; gap: .5rem; margin-bottom: 1.25rem; }
.constraint {
    display: grid; grid-template-columns: 72px 1fr auto;
    align-items: center; gap: .75rem;
}
.constraint__label { font-size: .78rem; font-weight: 600; color: var(--text-muted); }
.constraint__bar {
    height: 8px; border-radius: 999px;
    background: var(--bg-inset); border: 1px solid var(--line);
    overflow: hidden;
}
.constraint__fill { display: block; height: 100%; border-radius: 999px; }
.constraint__fill--demand  { background: var(--demand); }
.constraint__fill--service { background: var(--service); }
.constraint__fill--supply  { background: var(--supply); }
.constraint__value { font-size: .8rem; white-space: nowrap; }
.constraint.is-binding .constraint__label { color: var(--text); }
.constraint.is-binding .constraint__value { color: var(--text); font-weight: 600; }
.constraint:not(.is-binding) .constraint__fill { opacity: .45; }

/* --- key/value blocks --- */

.kv { display: grid; gap: .45rem; }
.kv--wide { grid-template-columns: repeat(2, 1fr); gap: .55rem 1rem; }
@media (min-width: 700px) { .kv--wide { grid-template-columns: repeat(4, 1fr); } }
.kv > div { display: flex; justify-content: space-between; gap: .75rem; align-items: baseline; }
.kv--wide > div { flex-direction: column; gap: .1rem; align-items: flex-start; }
.kv__k { font-size: .78rem; color: var(--text-dim); }
.kv__v { font-size: .9rem; font-weight: 550; }

/* --- activity feed --- */

.feed { list-style: none; margin: 0; padding: 0; display: grid; gap: .7rem; }
.feed__item { padding-left: .7rem; border-left: 2px solid var(--line-strong); }
.feed__item--success { border-left-color: var(--positive); }
.feed__item--warning { border-left-color: var(--warning); }
.feed__title { font-size: .85rem; font-weight: 600; }
.feed__body  { font-size: .8rem; color: var(--text-muted); margin-top: .1rem; }

/* --------------------------------------------------------------- store page */

.btn--sm { padding: .4rem .8rem; font-size: .85rem; }

.buildings { display: grid; gap: .5rem; }

.building {
    display: flex; gap: 1rem; align-items: flex-start;
    padding: .85rem; border: 1px solid var(--line);
    border-radius: var(--radius-sm); background: var(--bg-inset);
}
.building.is-locked { opacity: .62; }
.building__main { flex: 1 1 auto; min-width: 0; }
.building__head { display: flex; align-items: baseline; gap: .6rem; margin-bottom: .2rem; }
.building__name  { font-weight: 600; font-size: .95rem; }
.building__level { font-size: .78rem; color: var(--text-muted); }
.building__desc  { margin: 0 0 .4rem; font-size: .82rem; color: var(--text-muted); line-height: 1.45; }

.building__effect { margin: 0; font-size: .82rem; color: var(--text-muted); }
.building__arrow  { margin: 0 .25rem; color: var(--text-dim); }
.building__effect .positive { color: var(--positive); }

.building__blocked {
    margin: .35rem 0 0; font-size: .78rem; color: var(--warning);
}

.building__action {
    flex: 0 0 auto; text-align: right;
    display: flex; flex-direction: column; gap: .3rem; align-items: flex-end;
    min-width: 108px;
}
.building__cost { font-size: .95rem; font-weight: 600; color: var(--accent); }
.building__cost.negative { color: var(--negative); }
.building__time { font-size: .76rem; }

@media (max-width: 560px) {
    .building { flex-direction: column; }
    .building__action { align-items: stretch; text-align: left; width: 100%; }
    .building__action form, .building__action .btn { width: 100%; }
}

/* --- countdown --- */

.countdown {
    font-size: 1.55rem; font-weight: 650; letter-spacing: -.02em;
    color: var(--accent); font-variant-numeric: tabular-nums;
}
.countdown.is-complete { color: var(--positive); }

.progress {
    height: 6px; margin-top: .55rem; border-radius: 999px;
    background: var(--bg-inset); border: 1px solid var(--line); overflow: hidden;
}
.progress__fill {
    display: block; height: 100%; width: 0;
    background: linear-gradient(90deg, var(--accent-dim), var(--accent));
    transition: width 1s linear;
}

.store-head__link { color: var(--text); text-decoration: none; }
.store-head__link:hover { color: var(--accent); text-decoration: none; }

.badge--building {
    color: var(--accent-hot);
    border-color: rgba(224,164,76,.4);
    background: var(--accent-ghost);
}

/* The pacing valve gets a quiet highlight: it is the one purchase whose value never
   shows up in the profit line, so it needs to catch the eye on its own. */
.building--pacing {
    border-color: var(--accent-dim);
    background: linear-gradient(180deg, var(--accent-ghost), var(--bg-inset) 60%);
}
.positive { color: var(--positive); }

/* --------------------------------------------------------------- staff */

.input--tiny {
    width: 58px; padding: .32rem .4rem; text-align: center;
    font-family: var(--mono); font-size: .85rem;
}
.hire-form { display: flex; gap: .35rem; align-items: center; justify-content: flex-end; }
.building__action .hire-form + .hire-form { margin-top: .1rem; }

.teams { display: grid; gap: .5rem; margin-bottom: 1rem; }
@media (min-width: 760px) { .teams { grid-template-columns: repeat(3, 1fr); } }

.team {
    padding: .7rem .8rem; border: 1px dashed var(--line-strong);
    border-radius: var(--radius-sm); background: var(--bg-inset);
}
.team.is-active {
    border-style: solid;
    border-color: rgba(109,218,168,.4);
    background: rgba(109,218,168,.07);
}
.team__head { display: flex; align-items: center; gap: .4rem; margin-bottom: .2rem; }
.team__name { font-size: .85rem; font-weight: 600; }
.team__desc { margin: 0; font-size: .78rem; color: var(--text-muted); line-height: 1.4; }
.team__missing { margin: .35rem 0 0; font-size: .76rem; color: var(--warning); }

/* --------------------------------------------------------------- finances */

.pl { display: grid; gap: .1rem; }
.pl__row {
    display: flex; align-items: baseline; justify-content: space-between;
    gap: 1rem; padding: .3rem 0;
}
.pl__row--total {
    border-top: 1px solid var(--line);
    margin-top: .2rem; padding-top: .5rem; font-weight: 600;
}
.pl__row--result {
    border-top: 2px solid var(--line-strong);
    margin-top: .3rem; padding-top: .6rem;
}
.pl__gap { height: .5rem; }
.pl__label  { font-size: .88rem; }
.pl__amount { font-size: .92rem; white-space: nowrap; }
.pl__row--result .pl__label  { font-size: 1rem; font-weight: 650; }
.pl__row--result .pl__amount { font-size: 1.25rem; font-weight: 650; }
.negative { color: var(--negative); }

.table-scroll { overflow-x: auto; }
.table { width: 100%; border-collapse: collapse; font-size: .86rem; }
.table th {
    text-align: left; font-size: .7rem; letter-spacing: .08em; text-transform: uppercase;
    color: var(--text-dim); font-weight: 700; padding: .4rem .6rem .5rem 0;
    border-bottom: 1px solid var(--line);
}
.table td { padding: .5rem .6rem .5rem 0; border-bottom: 1px solid var(--line); }
.table tr:last-child td { border-bottom: 0; }
.table .num { text-align: right; padding-right: 0; padding-left: .6rem; white-space: nowrap; }

.ledger { list-style: none; margin: 0; padding: 0; display: grid; gap: .3rem; }
.ledger__row { display: flex; justify-content: space-between; gap: .75rem; font-size: .82rem; }
.ledger__type { color: var(--text-muted); text-transform: capitalize; }
.ledger__amount { white-space: nowrap; }

/* --------------------------------------------------------------- status bar

   Present on every authenticated page and refreshed by the 30-second poll. Cash, hourly
   profit and anything on a clock, always visible without navigating anywhere — which is
   most of the difference between a game and a set of forms. */

.statusbar {
    position: sticky; top: 57px; z-index: 25;
    background: rgba(20, 25, 34, .95);
    backdrop-filter: blur(10px);
    border-bottom: 1px solid var(--line);
}
.statusbar__inner {
    max-width: 1240px; margin: 0 auto;
    padding: .45rem 1.25rem;
    display: flex; align-items: center; gap: 1.5rem;
}
.statusbar__stat { display: flex; align-items: baseline; gap: .45rem; flex: none; }
.statusbar__stat--wide { flex: 1 1 auto; min-width: 0; }
.statusbar__label {
    font-size: .66rem; font-weight: 700; letter-spacing: .09em;
    text-transform: uppercase; color: var(--text-dim);
}
.statusbar__value { font-size: .92rem; font-weight: 600; }
.statusbar__value.is-negative { color: var(--negative); }

.statusbar__queues {
    display: flex; gap: .4rem; align-items: center;
    overflow-x: auto; scrollbar-width: none; font-size: .8rem;
}
.statusbar__queues::-webkit-scrollbar { display: none; }

.chip {
    display: inline-flex; align-items: baseline; gap: .4rem;
    padding: .16rem .5rem; border-radius: 999px; white-space: nowrap;
    border: 1px solid var(--line-strong); background: var(--bg-inset);
}
.chip--construction { border-color: rgba(196,143,240,.35); }
.chip--recruitment  { border-color: rgba(109,218,168,.35); }
.chip--training     { border-color: rgba(224,164,76,.35); }
.chip__label { font-size: .76rem; color: var(--text-muted); }
.chip__time  { font-size: .76rem; color: var(--accent); font-variant-numeric: tabular-nums; }

.statusbar__bell {
    position: relative; flex: none;
    font-size: .78rem; font-weight: 600; color: var(--text-muted);
    padding: .25rem .1rem;
}
.statusbar__bell:hover { color: var(--text); text-decoration: none; }
.statusbar__badge {
    position: absolute; top: -4px; right: -14px;
    min-width: 17px; height: 17px; padding: 0 4px;
    display: grid; place-items: center;
    border-radius: 999px; background: var(--negative); color: #fff;
    font-size: .64rem; font-weight: 700; font-family: var(--mono);
}

/* --------------------------------------------------------------- notifications */

.notices { list-style: none; margin: 0; padding: 0; }
.notice {
    display: flex; gap: .8rem;
    padding: .85rem 0; border-bottom: 1px solid var(--line);
}
.notice:last-child { border-bottom: 0; }
.notice__body { flex: 1 1 auto; min-width: 0; border-left: 2px solid var(--line-strong); padding-left: .8rem; }
.notice--success .notice__body { border-left-color: var(--positive); }
.notice--warning .notice__body { border-left-color: var(--warning); }
.notice.is-unread .notice__body { border-left-width: 3px; }
.notice.is-unread .notice__title { color: var(--text); }
.notice:not(.is-unread) .notice__title { color: var(--text-muted); }

.notice__head { display: flex; align-items: baseline; gap: .75rem; justify-content: space-between; }
.notice__title { font-size: .92rem; font-weight: 600; }
.notice__time  { font-size: .76rem; white-space: nowrap; flex: none; }
.notice__text  { margin: .2rem 0 0; font-size: .85rem; color: var(--text-muted); line-height: 1.5; }
.notice__link  { display: inline-block; margin-top: .35rem; font-size: .8rem; }

.pager { display: flex; align-items: center; justify-content: center; gap: 1rem; margin-top: 1rem; }

@media (max-width: 720px) {
    .statusbar__inner { padding: .4rem .9rem; gap: .9rem; }
    .statusbar__stat--wide { display: none; }   /* chips need room; the badge is enough here */
    .statusbar__label { display: none; }
    .statusbar__value { font-size: .85rem; }
}

/* --------------------------------------------------------------- tabs

   Implemented with radio inputs and sibling selectors rather than JavaScript, so the store
   page keeps working with scripting off — the same standard the rest of the game holds to.
   The inputs are visually hidden but focusable, so keyboard and screen-reader users get
   real radio-group semantics for free. */

.tabs__radio {
    position: absolute; opacity: 0; width: 1px; height: 1px;
    margin: -1px; overflow: hidden; clip: rect(0 0 0 0);
}
.tabs__bar {
    display: flex; gap: .25rem; margin-bottom: 1rem;
    border-bottom: 1px solid var(--line);
}
.tabs__tab {
    position: relative; cursor: pointer; user-select: none;
    padding: .55rem .9rem; margin-bottom: -1px;
    font-size: .88rem; font-weight: 600; color: var(--text-muted);
    border-bottom: 2px solid transparent;
    display: inline-flex; align-items: center; gap: .4rem;
}
.tabs__tab:hover { color: var(--text); }
.tabs__count {
    font-size: .72rem; padding: .05rem .35rem; border-radius: 999px;
    background: var(--bg-hover); color: var(--text-dim);
}
.tabs__dot {
    width: 6px; height: 6px; border-radius: 999px; background: var(--accent);
}

/* Only the panel matching the checked radio is shown. */
.tabs__panel { display: none; }
#tab-overview:checked  ~ .grid .tabs__panel--overview,
#tab-staff:checked     ~ .grid .tabs__panel--staff,
#tab-buildings:checked ~ .grid .tabs__panel--buildings { display: block; }

#tab-overview:checked  ~ .tabs__bar [for="tab-overview"],
#tab-staff:checked     ~ .tabs__bar [for="tab-staff"],
#tab-buildings:checked ~ .tabs__bar [for="tab-buildings"] {
    color: var(--accent-hot);
    border-bottom-color: var(--accent);
}
.tabs__radio:focus-visible ~ .tabs__bar label { outline: none; }
#tab-overview:focus-visible  ~ .tabs__bar [for="tab-overview"],
#tab-staff:focus-visible     ~ .tabs__bar [for="tab-staff"],
#tab-buildings:focus-visible ~ .tabs__bar [for="tab-buildings"] {
    outline: 2px solid var(--accent); outline-offset: -2px; border-radius: var(--radius-sm);
}

@media (max-width: 560px) {
    .tabs__bar { overflow-x: auto; scrollbar-width: none; }
    .tabs__bar::-webkit-scrollbar { display: none; }
    .tabs__tab { white-space: nowrap; padding: .5rem .7rem; }
}

/* --------------------------------------------------------------- market & rankings */

.location + .location { margin-top: 1rem; }
.location--mine   { border-color: rgba(109,218,168,.35); }
.location--locked { opacity: .72; }

.location__head {
    display: flex; align-items: flex-start; justify-content: space-between;
    gap: 1rem; flex-wrap: wrap; margin-bottom: .9rem;
}
.location__name { font-size: 1.05rem; margin: 0 0 .1rem; display: flex; align-items: center; gap: .5rem; flex-wrap: wrap; }
.location__meta { margin: 0; font-size: .8rem; }
.location__slots { font-size: .85rem; white-space: nowrap; }

/* A single bar showing the whole street: every player's slice, then whatever the
   established retailers still hold. It is the clearest statement the game can make that
   the customer pool is finite and shared. */
.sharebar {
    display: flex; height: 10px; border-radius: 999px; overflow: hidden;
    background: var(--bg-inset); border: 1px solid var(--line);
}
.sharebar__seg { display: block; height: 100%; background: var(--demand); }
.sharebar__seg--mine      { background: var(--service); }
.sharebar__seg--incumbent { background: var(--line-strong); }
.sharebar__seg + .sharebar__seg { border-left: 1px solid var(--bg-panel); }

.standings { list-style: none; margin: .6rem 0 0; padding: 0; display: grid; gap: .3rem; }
.standings__row {
    display: flex; align-items: baseline; gap: .6rem;
    font-size: .85rem; padding: .18rem 0;
}
.standings__row.is-me { color: var(--service); font-weight: 600; }
.standings__row--incumbent { border-top: 1px solid var(--line); padding-top: .4rem; margin-top: .2rem; }
.standings__rank  { width: 1.4rem; color: var(--text-dim); font-size: .78rem; flex: none; }
.standings__name  { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.standings__value { flex: none; }

.table tr.is-me td { background: rgba(109,218,168,.07); }
.table tr.is-me td:first-child { box-shadow: inset 2px 0 0 var(--service); }

/* Board switcher reuses the tab bar, but as real links rather than radio labels. */
.tabs__bar a.tabs__tab { text-decoration: none; }
.tabs__bar a.tabs__tab.is-current {
    color: var(--accent-hot);
    border-bottom-color: var(--accent);
}

/* --------------------------------------------------------------- objectives & events */

.missions { display: grid; gap: .75rem; }

.mission {
    padding: .9rem 1rem; border: 1px solid var(--line);
    border-radius: var(--radius-sm); background: var(--bg-inset);
}
.mission--completed { border-color: rgba(106,169,245,.4); background: rgba(106,169,245,.06); }
.mission--claimed   { opacity: .6; }

.mission__head { display: flex; align-items: center; gap: .5rem; margin-bottom: .25rem; }
.mission__name { font-size: .95rem; font-weight: 650; }
.mission__desc { margin: 0 0 .5rem; font-size: .85rem; color: var(--text-muted); line-height: 1.5; }

.mission__reqs { margin: 0 0 .55rem; padding-left: 1.1rem; font-size: .82rem; }
.mission__reqs li { margin: .1rem 0; }

.mission__progress {
    height: 5px; border-radius: 999px; overflow: hidden;
    background: var(--bg-panel); border: 1px solid var(--line);
}
.mission__fill { display: block; height: 100%; background: var(--demand); transition: width .4s ease; }

.mission__hint {
    margin: .45rem 0 0; font-size: .8rem; color: var(--accent);
}
.mission__foot {
    display: flex; align-items: center; justify-content: space-between;
    gap: .75rem; margin-top: .65rem;
}
.mission__reward { font-size: .8rem; }

.event {
    padding: .85rem 1rem; margin-bottom: 1rem;
    border: 1px solid var(--accent-dim); border-radius: var(--radius);
    background: linear-gradient(180deg, var(--accent-ghost), var(--bg-panel) 70%);
}
.event__head { display: flex; align-items: baseline; justify-content: space-between; gap: 1rem; }
.event__name { font-size: 1rem; font-weight: 650; color: var(--accent-hot); }
.event__time { font-size: .85rem; color: var(--accent); }
.event__desc { margin: .3rem 0 .6rem; font-size: .85rem; color: var(--text-muted); line-height: 1.5; }
.event__mods { display: flex; gap: .35rem; flex-wrap: wrap; }

.panel--objective { margin-bottom: 1rem; border-color: var(--line-strong); }
.panel--objective .mission { border: 0; background: transparent; padding: 0; }

/* --------------------------------------------------------------- admin

   Deliberately unlike the game. Somebody with both windows open should never be in doubt
   about which one can change the rules for everybody. Cooler, denser, no warm accent. */

body.is-admin { background-image: none; background: #0a0d13; }

.admin-header { border-bottom: 1px solid var(--line-strong); background: #0f131b; }
.admin-header__inner {
    max-width: 1500px; margin: 0 auto; padding: .6rem 1.25rem;
    display: flex; align-items: center; gap: 1.5rem; flex-wrap: wrap;
}
.admin-brand {
    display: inline-flex; align-items: center; gap: .55rem;
    color: var(--text); text-decoration: none; font-size: .95rem;
}
.admin-brand:hover { text-decoration: none; color: var(--text); }
.admin-brand strong { color: var(--demand); font-weight: 700; }
.admin-brand__mark {
    width: 24px; height: 24px; display: grid; place-items: center;
    border-radius: 6px; background: var(--demand); color: #08101c;
    font-weight: 800; font-size: .74rem;
}

.admin-nav { display: flex; gap: .2rem; margin-left: auto; }
.admin-nav a {
    padding: .35rem .7rem; border-radius: var(--radius-sm);
    font-size: .86rem; font-weight: 500; color: var(--text-muted);
}
.admin-nav a:hover { background: var(--bg-hover); color: var(--text); text-decoration: none; }
.admin-nav a.is-active { background: rgba(106,169,245,.14); color: var(--demand); }

.admin-exit { font-size: .82rem; color: var(--text-dim); }

.admin-subnav {
    max-width: 1500px; margin: 0 auto; padding: 0 1.25rem .55rem;
    display: flex; gap: .15rem; overflow-x: auto; scrollbar-width: none;
}
.admin-subnav::-webkit-scrollbar { display: none; }
.admin-subnav a {
    padding: .25rem .55rem; border-radius: var(--radius-sm); white-space: nowrap;
    font-size: .78rem; color: var(--text-dim);
}
.admin-subnav a:hover { background: var(--bg-hover); color: var(--text-muted); text-decoration: none; }
.admin-subnav a.is-active { background: var(--bg-hover); color: var(--demand); }

.admin-main { max-width: 1500px; margin: 0 auto; padding: 1.5rem 1.25rem 4rem; }
.admin-main h1 { font-size: 1.35rem; }

.admin-search { display: flex; gap: .5rem; align-items: center; margin-bottom: 1rem; max-width: 520px; }
.admin-actions { display: flex; gap: .3rem; flex-wrap: wrap; align-items: center; }
.admin-cash { display: flex; gap: .25rem; align-items: center; }

.input--cell {
    width: 92px; padding: .28rem .4rem; font-size: .8rem; text-align: right;
}
.admin-cash .input--cell:nth-of-type(2) { width: 130px; text-align: left; }

.table--dense td, .table--dense th { padding: .3rem .5rem .3rem 0; font-size: .82rem; }
.table tr.is-disabled { opacity: .45; }

/* A compact select for the expansion table, where the control sits inline in a cell. */
.input--sm {
    width: auto;
    display: inline-block;
    padding: 0.3rem 0.5rem;
    font-size: 0.85rem;
    margin: 0 0.35rem 0 0;
}

/* The item waiting behind whatever is running. Deliberately quieter than the active
   panel: it is information, not the thing the player is watching count down. */
.queued {
    margin-top: 0.9rem;
    padding-top: 0.9rem;
    border-top: 1px dashed var(--border);
}
.queued__label {
    font-size: 0.7rem;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--text-dim);
    margin-bottom: 0.35rem;
}
.building__queueable {
    margin: 0.35rem 0 0;
    font-size: 0.82rem;
    color: var(--text-dim);
}

/* Language switcher in the header. Sits beside sign out, outside the scrolling nav, for
   the same reason sign out does: it must be findable on a phone. */
.app-language { display: flex; align-items: center; margin-right: 0.6rem; }
.app-language .input--sm { min-width: 7.5rem; }
.visually-hidden {
    position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
    overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* The language switcher under the sign-in card. Quiet: it is a way out of the wrong
   language, not a call to action. */
.auth-language { display: flex; justify-content: center; margin-top: 1rem; }
.auth-language .app-language { margin-right: 0; }
