/*
 * Infinite CEO -- desktop theme "Executive Terminal" (near-black, hairline rules, monospace
 * figures, amber signal color -- a Bloomberg-desk feel), reskinned to a touch-first "Modern
 * Tile" theme under the mobile breakpoint below. Self-contained: no CDN, no external fonts --
 * this app's CSP is style-src/font-src 'self' only, so both themes lean on system font stacks
 * rather than the webfonts used in the original design mockups.
 *
 * Most components (cards, buttons, inputs, panels) are themed entirely through the custom
 * properties below, so the mobile media query at the bottom only needs to redefine those
 * properties plus the handful of structural rules (sidebar vs. bottom tab bar, ticker,
 * radius) that actually differ between the two directions.
 */

:root {
    --bg: #0a0c0f;
    --bg-panel: #101317;
    --bg-panel-alt: #0d0f12;
    --border: #22262c;
    --text: #c7ccd1;
    --text-bright: #e8e9eb;
    --text-dim: #5d6369;
    --accent: #e8a33d;
    --accent-strong: #f4bc63;
    --good: #4caf6d;
    --bad: #e05252;
    --warn: #e8a33d;
    /* Every moment the game puts a CHOICE in front of the player: a crisis, an opportunity, a
       rival's move, an executive's proposal, a dilemma. Deliberately neither green nor red --
       a colour that announces the answer lets a player work the entire event system without
       reading a word of it, and reading it is the game. Distinct from the amber of routine
       controls too, so a decision still arrives as an event rather than as another button. */
    --event: #3fb9d4;
    --radius: 4px;
    --font: -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
    --font-mono: ui-monospace, "SFMono-Regular", Consolas, "Liberation Mono", Menlo, monospace;
}

* { box-sizing: border-box; }

html, body {
    background: var(--bg);
    color: var(--text);
    font-family: var(--font);
    margin: 0;
}

a { color: var(--accent-strong); }

h1, h2, h3 { line-height: 1.2; }

.top-nav {
    display: flex;
    align-items: center;
    gap: 1.5rem;
    padding: 0.75rem 1.5rem;
    border-bottom: 1px solid var(--border);
    background: var(--bg-panel);
}

/* Matches DWO's .parent-link exactly (same Dons AI Lab convention every game in the lab uses) --
   font-size 0.72rem, uppercase, dim, no underline. Sits first in .top-nav's flex row so it reads
   left of the brand without any extra layout work. */
.parent-link {
    font-size: 0.72rem;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--text-dim);
    text-decoration: none;
    white-space: nowrap;
}
.parent-link:hover, .parent-link:focus-visible { color: var(--text-bright); }

.top-nav .brand {
    font-weight: 700;
    font-size: 1.1rem;
    font-family: var(--font-mono);
    letter-spacing: 0.02em;
    color: var(--text-bright);
    text-decoration: none;
}

.top-nav nav { display: flex; gap: 1rem; flex: 1; }
.top-nav nav a { text-decoration: none; color: var(--text-dim); }
.top-nav nav a:hover, .top-nav nav a:focus-visible { color: var(--text); }
.account { display: flex; gap: 0.75rem; align-items: center; color: var(--text-dim); }

main { max-width: 1200px; margin: 0 auto; padding: 1.5rem; }

.site-footer {
    text-align: center;
    padding: 2rem 1rem;
    color: var(--text-dim);
}

/* CSS-only portrait lock: invisible unless the viewport is both narrow AND landscape. */
.rotate-lock {
    display: none;
    position: fixed;
    inset: 0;
    z-index: 999;
    background: var(--bg);
    align-items: center;
    justify-content: center;
    text-align: center;
    padding: 2rem;
}
.rotate-lock-message { color: var(--text-bright); font-size: 1.1rem; max-width: 24rem; }
/*
 * Gate on (hover: none) and (pointer: coarse) -- the media features that reliably identify a
 * touch-primary device (phone or tablet) -- not just a width/height threshold. A phone or
 * tablet has no hover-capable pointer, but an ordinary desktop browser window does, even when
 * resized narrow (e.g. a split-screen desktop window is still "landscape" by aspect ratio).
 * Without this distinction, narrowing a desktop window below the threshold would incorrectly
 * trip the lock on a screen that can't be rotated at all.
 */
@media (orientation: landscape) and (hover: none) and (pointer: coarse) {
    .rotate-lock { display: flex; }
    .top-nav, main, .site-footer { display: none; }
}

.panel {
    background: var(--bg-panel);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: 1.5rem;
}

.landing { text-align: center; padding: 4rem 1rem; }
.landing .tagline { color: var(--text-dim); max-width: 40rem; margin: 1rem auto 2rem; }
.landing-links { margin-top: 1rem; display: flex; gap: 1.5rem; justify-content: center; }

.cta {
    display: inline-block;
    background: var(--accent);
    color: #14151d;
    padding: 0.75rem 1.5rem;
    border-radius: var(--radius);
    text-decoration: none;
    font-weight: 700;
}
.cta:hover, .cta:focus-visible { background: var(--accent-strong); }

/* Forms */
form label {
    display: flex;
    flex-direction: column;
    gap: 0.35rem;
    margin-bottom: 1rem;
    font-size: 0.9rem;
    color: var(--text-dim);
}

input, select, textarea, button {
    font-family: inherit;
    font-size: 1rem;
}

input, select, textarea {
    background: var(--bg-panel-alt);
    border: 1px solid var(--border);
    color: var(--text);
    border-radius: 6px;
    padding: 0.5rem 0.6rem;
}

input:focus-visible, select:focus-visible, textarea:focus-visible, button:focus-visible {
    outline: 2px solid var(--accent-strong);
    outline-offset: 1px;
}

/* The optional product-name field sits above its description textarea inside .product-pitch (see PITCH_ACTIONS/renderDashboard in game.js) -- just needs a little breathing room between the two. */
.product-pitch input[type="text"] { display: block; width: 100%; margin-bottom: 0.5rem; }

.product-card button { margin-top: 0.5rem; margin-right: 0.4rem; }

button {
    background: var(--accent);
    color: #14151d;
    border: none;
    border-radius: 6px;
    padding: 0.6rem 1.2rem;
    cursor: pointer;
    font-weight: 700;
}
button:hover { background: var(--accent-strong); }
button:disabled { opacity: 0.5; cursor: not-allowed; }
button.secondary { background: var(--bg-panel-alt); border: 1px solid var(--border); color: var(--text); }

.hint { color: var(--text-dim); font-size: 0.8rem; }
.error { color: var(--bad); font-weight: 600; }
.gameover-epitaph { font-style: italic; font-size: 1.05rem; max-width: 42rem; }

/* The one place a colour is allowed to carry a verdict. These are not choices -- they are the
   game telling a CEO that the board is close to firing them, that the company is close to
   running out of money, that someone is close to buying it out from under them. That is how
   such news reaches a real chief executive, and the urgency is part of the information. */
.warning-banner {
    background: color-mix(in srgb, var(--bad) 12%, var(--bg-panel-alt));
    border: 1px solid var(--bad);
    border-radius: var(--radius);
    padding: 0.75rem 1rem;
    margin-bottom: 1rem;
}
.warning-banner strong { color: var(--bad); }
.warning-banner ul { margin: 0.4rem 0 0; padding-left: 1.2rem; }
.warning-banner li { margin-bottom: 0.15rem; }

/*
 * Every moment that puts a choice to the player wears the same clothes: a crisis, an
 * opportunity, a rival's move, an executive's proposal, a dilemma. It is still a live event
 * with a countdown rather than a slow-building consequence of trending stats -- that is what
 * .warning-banner is for -- and it still carries its own button rather than making the player
 * hunt for the response in the Strategic Actions list.
 *
 * What changed is the colour. Crises were red and opportunities green, down to a filled button
 * in the matching colour, which meant a player could work the entire event system without
 * reading any of it: press the green one, brace for the red one. Whether a choice turns out
 * well is the question being asked; it cannot also be the answer on display. Some of these are
 * ruinous and some are the best thing that happens all year, and telling them apart is the
 * skill the game is actually testing.
 *
 * So the treatment is vivid rather than muted -- the accent bar, the filled button, a colour
 * used nowhere else in the interface. These are the moments a run turns on and they should
 * feel like it. They just must not feel like a verdict.
 */
.event-banner {
    background: color-mix(in srgb, var(--event) 13%, var(--bg-panel-alt));
    border: 1px solid var(--event);
    border-left: 3px solid var(--event);
    border-radius: var(--radius);
    padding: 0.75rem 1rem;
    margin-bottom: 1rem;
    display: grid;
    gap: 0.4rem;
}
.event-banner-head { display: flex; justify-content: space-between; align-items: baseline; gap: 0.75rem; }
.event-banner-head strong { color: var(--event); }
.event-action-btn {
    justify-self: start;
    background: var(--event);
    color: #07222a;
    border: none;
}
.event-action-btn:hover { background: color-mix(in srgb, var(--event) 85%, #fff); }

/* A dilemma offers two real options and neither of them is the default. They share one row, at
   the same size and in the same colour, so the layout gives away no more than the palette
   does -- there is no button that is obviously the safe one to press. */
.event-options { display: flex; flex-wrap: wrap; gap: 0.5rem; }
.event-options .event-action-btn { justify-self: auto; }

/* Feedback overlay: every action result, centered over the viewport regardless of
   where the dashboard is scrolled to. */
.feedback-overlay {
    position: fixed;
    inset: 0;
    background: rgba(4, 6, 12, 0.6);
    display: flex;
    align-items: center;
    justify-content: center;
    z-index: 100;
    padding: 1rem;
}
/* Same equal-specificity trap as .tab-panel: without this, [hidden] loses to the rule
   above and the overlay stays visible even while the hidden attribute is true. */
.feedback-overlay[hidden] { display: none; }
.feedback-box {
    background: var(--bg-panel);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: 1.5rem;
    max-width: 26rem;
    width: 100%;
    box-shadow: 0 20px 60px rgba(0, 0, 0, 0.5);
}
#feedback-message { font-size: 1rem; line-height: 1.4; }
.feedback-overlay.is-error #feedback-message { color: var(--bad); font-weight: 600; }
.feedback-cost {
    margin-top: 0.75rem;
    padding: 0.6rem 0.75rem;
    background: var(--bg-panel-alt);
    border: 1px solid var(--border);
    border-radius: 6px;
    font-size: 0.85rem;
    font-family: var(--font-mono);
    color: var(--text-dim);
}
.feedback-box button { margin-top: 1.1rem; width: 100%; }

/* Game shell */
/* Desktop only: pins the shell to the viewport below .top-nav (measured at 46px) so only
   .game-main scrolls internally -- the ticker, topbar, and sidebar stay put while a player
   scrolls a long tab (e.g. News). Reset back to natural document flow on mobile below, which
   keeps its own sticky-topbar/fixed-bottom-tabs approach instead (see the comment on
   .game-shell's overflow: visible in the mobile media query for why the two techniques don't mix). */
.game-shell { padding: 0; overflow: hidden; height: calc(100vh - 46px); display: flex; flex-direction: column; }

/* Scrolling market ticker -- desktop only (see the mobile override at the bottom). Built by
   game.js from the live competitor/cycle/news data in the current GameView. */
.ticker-strip {
    height: 28px;
    background: var(--bg-panel-alt);
    border-bottom: 1px solid var(--border);
    overflow: hidden;
    display: flex;
    align-items: center;
}
.ticker-strip:empty { display: none; }
.ticker-track {
    display: flex;
    gap: 40px;
    white-space: nowrap;
    padding-left: 16px;
    font-family: var(--font-mono);
    font-size: 11px;
    color: var(--text-dim);
    animation: ticker-scroll 32s linear infinite;
}
.ticker-track .delta-up, .ticker-track .delta-down { font-weight: 600; }
@keyframes ticker-scroll {
    from { transform: translateX(0); }
    to { transform: translateX(-50%); }
}

.topbar {
    display: flex;
    align-items: center;
    gap: 1.5rem;
    flex-wrap: wrap;
    padding: 0.9rem 1.25rem;
    border-bottom: 1px solid var(--border);
}
#hdr-company-name { font-family: var(--font-mono); font-size: 1rem; color: var(--text-bright); letter-spacing: 0.02em; }
#hdr-week { color: var(--text-dim); margin-left: 0.6rem; font-size: 0.85rem; }
/* EP is the number a player needs to check before every single click -- bigger than the other
   topbar stats on purpose, not just another figure in the row. */
#hdr-ep { font-size: 1.3rem; }
.topbar-stats { display: flex; gap: 1.5rem; flex: 1; color: var(--text-dim); font-family: var(--font-mono); font-size: 0.9rem; }
.topbar-stats b { color: var(--text-bright); font-weight: 600; }

/* Sidebar (desktop) / bottom tab bar (mobile, see override below). */
.game-body { display: flex; align-items: stretch; flex: 1; min-height: 0; }
.game-main { flex: 1; min-width: 0; padding: 1.25rem; overflow-y: auto; }

/* Desktop only -- the tab list plus the persistent Company Detail tiles below it (see
   .sidebar-detail and #company-detail-sidebar in Play.cshtml), sharing one bordered column so
   they read as a single sidebar rather than two unrelated pieces. */
.sidebar-col { display: flex; flex-direction: column; width: 210px; flex-shrink: 0; border-right: 1px solid var(--border); }

.tabs {
    display: flex;
    flex-direction: column;
    flex-shrink: 0;
    padding: 0.75rem 0;
    gap: 0.1rem;
}

/* A second, compact rendering of the same Company Detail tiles renderDashboard() already builds
   -- single column, smaller type, no section heading (the tab list right above it already says
   where this is). Hidden on mobile (see the media query below), where the Dashboard tab's own
   copy (.dashboard-company-detail) is what shows instead -- there's no sidebar column on a phone
   to hang this off of. */
.sidebar-detail { padding: 0.6rem 0.7rem; overflow-y: auto; border-top: 1px solid var(--border); flex: 1; min-height: 0; }
.sidebar-detail h2 { display: none; }
.sidebar-detail .card-grid { display: flex; flex-direction: column; gap: 1px; }
.sidebar-detail .card { padding: 0.4rem 0.55rem; }
.sidebar-detail .card h3 { font-size: 0.58rem; margin-bottom: 0.15rem; }
.sidebar-detail .card .value { font-size: 0.8rem; }

/* Hidden on desktop by default -- the sidebar copy above is what shows there; this is the
   mobile-only fallback (no sidebar column exists in the bottom-tab-bar layout), toggled back on
   in the mobile media query below. */
.dashboard-company-detail { display: none; }

/* Leaving a run, which is a decision ABOUT the run rather than a move within it -- so it sits
   under the sidebar rather than among the Strategic Actions, in nobody's way and one click from
   anywhere. Deliberately quiet: no accent, no event cyan, no warning red. It is not an
   opportunity, it is not an emergency, and it must never be the brightest thing on screen. The
   confirm step is what stops a mis-click, not the styling. */
.sidebar-restart { padding: 0.55rem 0.7rem; border-top: 1px solid var(--border); flex-shrink: 0; }
.dashboard-restart { display: none; margin-top: 1.5rem; padding-top: 1rem; border-top: 1px solid var(--border); }
.restart-block button { width: 100%; font-size: 0.78rem; padding: 0.4rem 0.6rem; }
.restart-block .hint { margin: 0.35rem 0 0; line-height: 1.35; }
.restart-block .restart-confirm { margin-bottom: 0.3rem; }

/* The way back out of the founding form when it was reached mid-run. */
.create-return {
    background: var(--bg-panel-alt);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: 0.75rem 1rem;
    margin-bottom: 1.25rem;
}
.create-return .hint { margin: 0 0 0.6rem; }
.tab-btn {
    background: transparent;
    color: var(--text-dim);
    font-family: var(--font-mono);
    font-size: 0.8rem;
    letter-spacing: 0.03em;
    text-transform: uppercase;
    border: none;
    border-left: 2px solid transparent;
    border-radius: 0;
    text-align: left;
    padding: 0.55rem 1.25rem;
}
.tab-btn.active { color: var(--accent); border-left-color: var(--accent); background: var(--bg-panel-alt); }
.tab-btn:hover { color: var(--text); background: var(--bg-panel-alt); }

.tab-panel { display: grid; gap: 1rem; }
/* Equal specificity to the UA stylesheet's [hidden]{display:none}, and later in source order,
   so without this a hidden tab-panel would still render as a grid. */
.tab-panel[hidden] { display: none; }

/* Dense hairline-divided stat grid: the container's border color shows through a 1px gap
   between cells, so it reads as a ruled table without an actual <table>. */
.card-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
    gap: 1px;
    background: var(--border);
    border: 1px solid var(--border);
}

.card {
    background: var(--bg-panel-alt);
    padding: 0.85rem 1rem;
}
.card h3 {
    margin: 0 0 0.4rem;
    font-size: 0.7rem;
    font-family: var(--font-mono);
    color: var(--text-dim);
    text-transform: uppercase;
    letter-spacing: 0.06em;
    font-weight: 600;
}
.card .value { font-size: 1.15rem; font-family: var(--font-mono); font-weight: 600; color: var(--text-bright); }

/* Labeled progress bars -- Board Approval / Ethics / CEO Stress. A flat reading of "how close
   to trouble" that works the same as a compact bar on desktop or a rounded tile on mobile. */
.gauge-row { display: flex; gap: 1px; background: var(--border); border: 1px solid var(--border); margin-bottom: 0.9rem; }
.gauge { flex: 1; background: var(--bg-panel-alt); padding: 0.45rem 0.7rem; }
.gauge-head { display: flex; justify-content: space-between; font-size: 0.7rem; font-family: var(--font-mono); color: var(--text-dim); text-transform: uppercase; letter-spacing: 0.06em; }
.gauge-head span:last-child { color: var(--text-bright); font-size: 0.8rem; }
/* An inline SVG bar (width set via the `width` attribute in game.js), not a div sized with
   inline CSS -- this app's CSP (style-src 'self') blocks the `style="..."` attribute outright,
   but SVG presentation attributes like `width`/`fill` aren't CSS and are unaffected. */
.gauge-track { width: 100%; height: 4px; display: block; margin-top: 0.3rem; border-radius: 2px; overflow: hidden; }
.gauge-bg { fill: var(--bg); }
.gauge-fill.good { fill: var(--good); }
.gauge-fill.warn { fill: var(--warn); }
.gauge-fill.bad { fill: var(--bad); }

.action-list { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: 0.6rem; }
.action-list button {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 0.75rem;
    text-align: left;
    padding: 0.6rem 0.85rem;
}
.action-list button .hint { font-family: var(--font-mono); color: var(--accent); font-size: 0.75rem; }

.chart-container {
    position: relative;
    background: var(--bg-panel-alt);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: 1rem;
}
.price-chart-svg { width: 100%; height: 280px; display: block; }
.chart-gridline { stroke: var(--border); stroke-width: 1; }
.chart-axis-label { fill: var(--text-dim); font-size: 10px; }

/* Sits inside the chart card, top-right, so the toggle doesn't cost its own row of vertical space. */
.chart-toggle { position: absolute; top: 0.75rem; right: 0.75rem; display: flex; gap: 0.4rem; z-index: 1; }
.chart-toggle-btn { padding: 0.25rem 0.6rem; font-size: 0.8rem; }
.chart-toggle-btn.active { background: var(--accent); color: var(--bg); border-color: var(--accent); }

.chart-legend { display: flex; flex-wrap: wrap; gap: 0.75rem; margin-top: 0.5rem; }
.chart-legend-item { display: inline-flex; align-items: center; gap: 0.35rem; font-size: 0.8rem; color: var(--text-dim); }
.chart-swatch { width: 10px; height: 10px; display: inline-block; flex-shrink: 0; }

/* Explicit up/down text markers alongside color, for colorblind accessibility. */
.delta-up { color: var(--good); }
.delta-down { color: var(--bad); }
.delta-up::before { content: "▲ "; }
.delta-down::before { content: "▼ "; }

.data-table { width: 100%; border-collapse: collapse; }
.data-table th, .data-table td {
    text-align: left;
    padding: 0.5rem 0.75rem;
    border-bottom: 1px solid var(--border);
}
.data-table th { color: var(--text-dim); font-family: var(--font-mono); font-size: 0.75rem; text-transform: uppercase; letter-spacing: 0.04em; font-weight: 600; }
.data-table td { font-family: var(--font-mono); font-size: 0.85rem; }

/*
 * Markets, desktop: one dense hairline-divided grid (same technique as .card-grid) instead of
 * the old separate Competitors tab + tile grid + trading table -- all three used to show the
 * same handful of companies. Every ticker's trade controls stay inline in its own row, matching
 * the terminal's "everything visible, nothing to select first" density -- there's room for it.
 */
.markets-list { display: grid; gap: 1px; background: var(--border); border: 1px solid var(--border); }
.market-row {
    display: grid;
    grid-template-columns: 1.8fr 1.2fr 0.8fr 0.8fr 0.6fr 0.6fr 0.9fr 2.6fr;
    gap: 0.5rem;
    align-items: center;
    background: var(--bg-panel-alt);
    padding: 0.6rem 0.85rem;
    font-family: var(--font-mono);
    font-size: 0.85rem;
}
.market-header {
    font-size: 0.7rem;
    color: var(--text-dim);
    text-transform: uppercase;
    letter-spacing: 0.04em;
    padding: 0.5rem 0.85rem;
}
.market-swatch { margin-right: 0.5rem; vertical-align: middle; }
.market-col-industry { color: var(--text-dim); font-size: 0.8rem; }
.market-col-shares { color: var(--text-dim); font-size: 0.75rem; }
.market-col-trade { display: flex; align-items: center; gap: 0.4rem; }
.trade-qty-inline, .trade-panel-qty { width: 3.5rem; padding: 0.35rem 0.4rem; }
.trade-btn-inline, .trade-btn-panel { padding: 0.35rem 0.6rem; font-size: 0.78rem; }

/* A clicked row gets a left accent border -- only meaningful on mobile (it targets the shared
   trade panel), but harmless and gently informative on desktop too. */
.market-row.selected { border-left: 2px solid var(--accent); padding-left: calc(0.85rem - 2px); }

/* Hidden on desktop; only mobile shows a persistent trade panel (see the mobile override below). */
.trade-panel { display: none; }

/* Desktop already has explicit Long/Short columns -- the compact "10L" badge is a mobile-only
   stand-in for those columns (which get hidden there), so it stays off here to avoid showing the
   same holding twice. */
.market-holdings-badge { display: none; }

/* The board seat that comes with a controlling stake. A full-width strip under the row it
   belongs to, rather than another column: it is about that one company, not about any one
   number in the table. */
.board-seat-row {
    grid-column: 1 / -1;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.4rem;
    margin-top: 0.55rem;
    padding-top: 0.55rem;
    border-top: 1px solid var(--border);
    font-size: 0.78rem;
}
.board-seat-badge {
    background: var(--accent);
    color: var(--bg);
    padding: 0.15rem 0.45rem;
    border-radius: 2px;
    font-size: 0.68rem;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    white-space: nowrap;
}
.directive-btn, .replace-ceo-btn { padding: 0.3rem 0.55rem; font-size: 0.75rem; }
.directive-btn.active { border-color: var(--accent); color: var(--accent); }

.news-week-heading { margin: 1.1rem 0 0.4rem; font-size: 0.8rem; color: var(--text-dim); font-family: var(--font-mono); text-transform: uppercase; letter-spacing: 0.05em; }
.news-week-heading:first-child { margin-top: 0; }
.news-list { list-style: none; padding: 0; margin: 0; display: grid; gap: 0.5rem; }
.news-list li { background: var(--bg-panel-alt); border: 1px solid var(--border); border-radius: 6px; padding: 0.6rem 0.8rem; }

.help-panel dl { display: grid; grid-template-columns: max-content 1fr; gap: 0.4rem 1rem; }
.help-panel dt { font-weight: 600; }
.help-panel dd { margin: 0; color: var(--text-dim); }

/* Company-creation dice buttons: pick a random value for the field beside them. */
.field-with-dice { display: flex; gap: 0.5rem; align-items: center; }
.field-with-dice input { flex: 1; }
.dice-btn {
    flex-shrink: 0;
    width: 2.4rem;
    height: 2.4rem;
    padding: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--bg-panel-alt);
    border: 1px solid var(--border);
}
.dice-btn:hover { background: var(--border); }
.dice-btn { color: var(--text); }
.dice-btn svg { width: 1.3rem; height: 1.3rem; }

.icon-picker {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(48px, 1fr));
    gap: 0.5rem;
    margin-top: 0.4rem;
    max-height: 15rem;
    overflow-y: auto;
    padding: 0.25rem;
    background: var(--bg-panel-alt);
    border: 1px solid var(--border);
    border-radius: var(--radius);
}
.icon-swatch { padding: 0.35rem; background: transparent; border: 2px solid transparent; border-radius: 8px; }
.icon-swatch svg { width: 100%; height: 100%; display: block; }
.icon-swatch.selected { border-color: var(--accent); }
.icon-swatch:hover { background: var(--border); }

/* Header icon badge, next to the company name. */
#hdr-icon { display: inline-flex; width: 1.6rem; height: 1.6rem; vertical-align: middle; margin-right: 0.5rem; }
#hdr-icon svg { width: 100%; height: 100%; display: block; }
#hdr-icon[hidden] { display: none; }
.hdr-identity { display: flex; flex-direction: column; }
.hdr-identity-row { display: flex; align-items: center; }
/* Tight against the company name on purpose -- its own row, same subdued register as #hdr-week
   (lowercase, dim, small), just directly below rather than sharing the identity line. */
.hdr-industry { color: var(--text-dim); font-size: 0.78rem; text-transform: lowercase; margin-top: 0.1rem; }

/*
 * Mobile / tablet portrait -- "Modern Tile" theme (Direction B). Redefining the custom
 * properties above re-themes every component that already reads them (cards, buttons,
 * inputs, panels, the gauge bars, the chart); everything below this line is the handful of
 * structural rules that genuinely differ: bottom tab bar instead of a sidebar, rounded
 * tiles instead of hairline-divided grids, no ticker, and plain system fonts instead of the
 * desktop's monospace figures.
 */
@media (max-width: 700px) {
    :root {
        --bg: #121319;
        --bg-panel: #16171f;
        --bg-panel-alt: #1d1f2b;
        --border: #2a2d3d;
        --text: #e7e6ef;
        --text-bright: #ffffff;
        --text-dim: #9a98ac;
        --accent: #8a7bff;
        --accent-strong: #a396ff;
        --good: #63d47a;
        --bad: #ff9b6a;
        --warn: #e8a33d;
        --event: #4fd0e0;
        --radius: 14px;
    }

    .top-nav { flex-wrap: wrap; }
    main { padding: 1rem; }

    .top-nav .brand,
    #hdr-company-name, .topbar-stats, .tab-btn, .card h3, .card .value,
    .gauge-head, .data-table th, .data-table td {
        font-family: var(--font);
    }

    .ticker-strip { display: none; }

    /*
     * .game-shell's overflow: hidden (desktop-only need: it clips the ticker-strip's square
     * corners inside the panel's rounded top corners) makes it the nearest ancestor a sticky
     * descendant sticks relative to -- and since #game-shell itself never scrolls (the page's
     * <body> does), a sticky child inside it just behaves like position: relative instead of
     * actually sticking. The ticker is hidden entirely on mobile anyway, so there's nothing left
     * to clip here.
     */
    .game-shell { overflow: visible; height: auto; display: block; }

    /*
     * Sticky, not scroll-away: Cash / Company Value / EP / Advance Week are the numbers a
     * player needs while scanning Strategic Actions to decide what they can afford -- playtesting
     * on a phone-sized viewport showed the topbar scrolling out of view within the first couple
     * of stat cards, well before reaching the action buttons it exists to inform.
     */
    .topbar {
        padding: 0.6rem 1rem;
        border-radius: var(--radius) var(--radius) 0 0;
        position: sticky;
        top: 0;
        z-index: 40;
        background: var(--bg-panel);
        flex-wrap: wrap;
        row-gap: 0.3rem;
        column-gap: 0.75rem;
    }
    /* Two rows instead of one overflowing one: identity gets its own full-width row (with an
       ellipsis so a long company name can't push the layout wider than the screen), stats and
       the Advance Week button share the row below. */
    .hdr-identity { flex: 1 1 100%; order: 1; min-width: 0; }
    #hdr-company-name { font-size: 0.95rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 55vw; display: inline-block; vertical-align: middle; }
    #hdr-week { display: inline; font-size: 0.72rem; }
    .topbar-stats { order: 2; font-size: 0.78rem; gap: 0.7rem; flex: 1 1 auto; }
    #advance-week-btn { order: 3; flex: 0 0 auto; padding: 0.5rem 0.7rem; font-size: 0.8rem; white-space: nowrap; }

    /* Bottom tab bar instead of the desktop sidebar; leave room for it below the content. */
    .game-body { flex-direction: column; }
    /* No sidebar column on mobile -- .tabs becomes the fixed bottom bar (its own position:fixed
       rule below escapes .sidebar-col's flow regardless), and the persistent Company Detail
       sidebar has nowhere to live, so the Dashboard tab's own copy takes over instead. */
    .sidebar-col { width: auto; border-right: none; }
    .sidebar-detail { display: none; }
    .dashboard-company-detail { display: block; }
    .sidebar-restart { display: none; }
    .dashboard-restart { display: block; }
    .game-main { padding: 1rem; padding-bottom: 5rem; }
    .tabs {
        flex-direction: row;
        width: auto;
        border-right: none;
        border-top: 1px solid var(--border);
        background: var(--bg-panel);
        position: fixed;
        left: 0;
        right: 0;
        bottom: 0;
        z-index: 50;
        padding: 0.35rem 0.15rem calc(0.5rem + env(safe-area-inset-bottom));
        gap: 0;
        /* A narrow phone (7 tabs at once) can still be a few px tighter than every label needs --
           scroll rather than silently clip the last tab off the edge. */
        overflow-x: auto;
        -webkit-overflow-scrolling: touch;
    }
    .tab-btn {
        flex: 1 0 auto;
        min-width: 3.6rem;
        min-height: 44px;
        text-align: center;
        border-left: none;
        border-radius: 10px;
        font-size: 0.62rem;
        letter-spacing: 0.01em;
        padding: 0.4rem 0.1rem;
        white-space: nowrap;
    }
    .tab-btn.active { border-left: none; background: color-mix(in srgb, var(--accent) 18%, transparent); }

    /*
     * Two dense columns instead of one full-width card per stat -- each card previously cost
     * ~110-140px of scroll for a single label+value line. This is the "Company Detail" grid
     * only (see renderDashboard's reordering): it now sits below Strategic Actions, so it's
     * fine for it to be denser and less prominent -- it's reference info, browsed occasionally,
     * not the thing a player scans every week.
     */
    .card-grid { grid-template-columns: repeat(2, 1fr); gap: 0.5rem; background: none; border: none; }
    .card { border-radius: var(--radius); border: 1px solid var(--border); padding: 0.55rem 0.7rem; }
    .card h3 { font-size: 0.62rem; margin-bottom: 0.15rem; }
    .card .value { font-size: 0.95rem; }
    .stat-detail-heading { color: var(--text-dim); font-size: 0.95rem; margin-top: 1.5rem; }

    .gauge-row { gap: 0.75rem; background: none; border: none; flex-wrap: wrap; }
    .gauge { border-radius: var(--radius); border: 1px solid var(--border); min-width: 45%; }

    /*
     * Label above its cost badge instead of side-by-side -- squeezing both onto one row on a
     * 375px screen was forcing "International Expansion" and its cost badge to wrap unpredictably
     * across two ragged lines. Stacked, each is one clean line and the button height is smaller
     * and more consistent, not larger.
     */
    .action-list button { border-radius: var(--radius); min-height: 44px; flex-direction: column; align-items: flex-start; gap: 0.15rem; }
    .action-list button .hint { color: var(--text-dim); }

    /*
     * The Workforce table is the second-most-scrolled screen (8 departments + 5 executives),
     * and a plain HTML <table> just makes its columns awkwardly narrow at this width rather
     * than reflowing -- Hire/Lay Off ended up stacking to ~270px per row. This turns each row
     * into a compact two-line flex block instead: department + staff count on top, action
     * buttons filling a row underneath.
     */
    #tab-workforce table, #tab-workforce tbody, #tab-workforce tr, #tab-workforce td { display: block; width: 100%; }
    #tab-workforce thead { display: none; }
    #tab-workforce tr {
        display: flex;
        flex-wrap: wrap;
        align-items: center;
        padding: 0.6rem 0;
        border-bottom: 1px solid var(--border);
        gap: 0.4rem;
    }
    #tab-workforce td { border: none; padding: 0; }
    #tab-workforce td:first-child { flex: 1 1 auto; font-weight: 600; }
    #tab-workforce td:nth-child(2) { flex: 0 0 auto; color: var(--text-dim); font-size: 0.85rem; }
    #tab-workforce td:last-child { flex: 1 1 100%; display: flex; gap: 0.5rem; }
    #tab-workforce td:last-child button { flex: 1; min-height: 42px; font-size: 0.78rem; padding: 0.4rem 0.5rem; flex-direction: column; gap: 0.1rem; }

    /*
     * Markets, mobile: no room for a 7-column terminal row, let alone a fourth trade button per
     * row -- each ticker collapses to one compact price line (name, price, change, a tiny
     * holdings badge if any), and the header row/industry/explicit long-short columns/inline
     * trade controls that only make sense at desktop width are dropped entirely. Tapping a row
     * aims the single shared trade panel below the list at it instead of repeating four buttons
     * per row.
     *
     * The chart is also shorter here than on desktop -- with a fixed trade panel now permanently
     * docked over the bottom ~200px of the screen, a full-height chart pushed the ticker list
     * (the thing a player is actually here to look at and act on) out from under the fold
     * entirely.
     */
    .price-chart-svg { height: 140px; }
    .markets-list { background: none; border: none; gap: 0.5rem; }
    .market-header { display: none; }
    .market-row {
        grid-template-columns: 1fr auto auto;
        border-radius: var(--radius);
        border: 1px solid var(--border);
        min-height: 44px;
        font-size: 0.85rem;
    }
    .market-row.selected { border-color: var(--accent); padding-left: 0.85rem; }
    .market-col-industry, .market-col-held, .market-col-trade, .market-col-shares { display: none; }
    .market-holdings-badge {
        display: inline-block;
        background: var(--bg-panel);
        color: var(--accent-strong);
        font-family: var(--font);
        font-size: 0.65rem;
        font-weight: 700;
        padding: 0.1rem 0.4rem;
        border-radius: 999px;
        margin-left: 0.4rem;
    }

    /*
     * Docked just above the bottom tab bar, like the tab bar itself -- position: fixed, not
     * sticky. Sticky's "stuck" position is relative to how much room is left in its own normal
     * flow, and on a short list (3-4 tickers) that math can resolve to the panel floating up
     * over the list instead of sitting below it; fixed always anchors to the viewport itself.
     */
    .trade-panel {
        display: block;
        position: fixed;
        left: 1rem;
        right: 1rem;
        bottom: calc(3.5rem + env(safe-area-inset-bottom));
        z-index: 45;
        margin-top: 0;
        background: var(--bg-panel-alt);
        border: 1px solid var(--border);
        border-radius: var(--radius);
        padding: 0.75rem 0.85rem;
        box-shadow: 0 -6px 20px rgba(0, 0, 0, 0.25);
    }
    .trade-panel-head { font-weight: 700; margin-bottom: 0.5rem; }
    .trade-panel-controls { display: flex; flex-wrap: wrap; gap: 0.4rem; }
    .trade-panel-controls button { flex: 1; min-width: 4rem; min-height: 42px; }
    .trade-panel-qty { width: 100%; flex: 1 1 100%; }

    /* Room for the fixed trade panel + tab bar so the last ticker row isn't hidden behind them. */
    #tab-markets { padding-bottom: 11rem; }
}
