/* Phase 0 shell styling. Deliberately spare — a sandbox, not a skin. */

:root {
    --bg: #1b1b1f;
    --panel: #26262c;
    --ink: #e6e6ea;
    --muted: #9a9aa6;
    --accent: #6db3f2;
    --border: #3a3a44;
}

* { box-sizing: border-box; }

body {
    margin: 0;
    background: var(--bg);
    color: var(--ink);
    font: 14px/1.45 system-ui, -apple-system, Segoe UI, sans-serif;
}

#app {
    max-width: 1040px;
    margin: 0 auto;
    /* No horizontal padding: the open-terrain region frame (960 game + 34px edge chevron each
       side = 1028px) must fit inside the prescaled 1040 viewport. 16px side padding would shrink
       the content box below 1028 and clip the chevroned frame. Vertical padding stays. */
    padding: 16px 0;
    display: flex;
    flex-direction: column;
    gap: 12px;
}

header.titlebar {
    display: flex;
    align-items: baseline;
    gap: 12px;
}
header.titlebar h1 { font-size: 18px; margin: 0; }
header.titlebar .tag {
    font-size: 12px;
    color: var(--muted);
}


/* The region stage. Habitat's playfield is 320×200 C64 pixels; we show it at an
   integer scale with nearest-neighbor so future art stays crisp. Phase 0 leaves it
   empty — Phase 1 mounts the inspector's regionView here. */
.stage {
    align-self: center;
    image-rendering: pixelated;
    background: #000;
    border: 1px solid var(--border);
    width: calc(320px * var(--scale, 2));
    height: calc(200px * var(--scale, 2));
    display: grid;
    place-items: center;
    color: var(--muted);
    font-size: 12px;
    user-select: none;
}

.statusbar {
    background: var(--panel);
    border: 1px solid var(--border);
    border-radius: 6px;
    padding: 6px 10px;
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
    font-size: 16px;
    color: var(--muted);
    min-height: 28px;
}
.statusbar .dot {
    display: inline-block;
    width: 10px; height: 10px;
    border-radius: 50%;
    margin-right: 7px;
    background: #555;
    vertical-align: middle;
}
.statusbar.online .dot { background: #58c25a; }
.statusbar.error .dot { background: #d8604a; }

/* ── Title sequence (Phase 0 capstone) ───────────────────────────────────── */
.title-stage {
    position: relative;
    align-self: center;
    margin-top: 24px;
    background: #000;
    border: 1px solid var(--border);
    overflow: hidden;
    cursor: pointer;
    image-rendering: pixelated;
}
.title-logo {
    /* The original C64 title silhouette (habsill3.m → assets/habsill.png) is the 320×128 bitmap
       band, which sat below the 9 text rows. Its sky pixels are transparent, so the .title-sky
       layer (and the comet between them) show through; the opaque silhouette occludes the comet.
       Place it in that band and upscale crisply (2× exact, so pixelated keeps the bits sharp). */
    position: absolute;
    left: 0;
    top: 36%;                 /* 72/200 — after the text rows */
    width: 100%;
    height: 64%;              /* 128/200 — the bitmap band */
    object-fit: fill;
    image-rendering: pixelated;
}
/* The sky: a solid fill behind the comet and the (sky-transparent) silhouette, filling the same
   bitmap band. C64 blue (color 6) — the "00" background the comet streaks across. */
.title-sky {
    position: absolute;
    left: 0;
    top: 36%;
    width: 100%;
    height: 64%;
    background: #2e2c9b;
}
.title-comet {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    pointer-events: none;     /* comet drawn in front of the backdrop (see title.js) */
}
/* "(c) 1987 Lucasfilm Ltd." — the C64 wrote this into the text rows above the bitmap band. */
.title-copyright {
    position: absolute;
    left: 0; right: 0;
    top: 18%;                 /* within the top text rows, above the silhouette band */
    text-align: center;
    color: #fff;
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
    font-size: 14px;
    letter-spacing: 1px;
    text-shadow: 0 1px 2px #000;
    pointer-events: none;
}
.title-prompt {
    position: absolute;
    left: 0; right: 0; bottom: 16px;
    text-align: center;
    color: var(--ink);
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
    font-size: 13px;
    text-shadow: 0 1px 3px #000;
    animation: blink 1.1s step-start infinite;
}
@keyframes blink { 50% { opacity: 0.25; } }

/* Avatar-name entry shown once the title finishes loading. The name is collected via the browser's
   native prompt (title.js) — a native dialog avoids the mobile zoom/scroll a page-embedded input
   triggers under the prescaled width=960 viewport — so this is just a button on a bottom panel. */
.title-login {
    position: absolute;
    left: 0; right: 0; bottom: 0;
    z-index: 3;
    display: flex;
    flex-direction: column;
    align-items: stretch;
    /* Opaque bottom panel + divider so the button sits on a clean bar rather than floating over
       the title cityscape (the earlier inline prompt overlapped the art). */
    padding: 14px 16px;
    box-sizing: border-box;
    background: #000;
    border-top: 2px solid #4a48a0;
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
}
.title-login-go {
    font: inherit; font-size: 16px;
    padding: 10px 12px; cursor: pointer;
    color: #fff; background: #2e2c9b;
    border: 1px solid #706deb; border-radius: 3px;
}
.title-login-go:hover { background: #4a48c0; }

/* C64 word balloon panel (Main/balloons.m) — charset border above the graphics band. */
.habitat-viewport {
    position: relative;
    line-height: 0;
}
/* Edge-transit frame: chevrons sit OUTSIDE the region canvas (left/right columns, bottom row)
   so they use the normal OS pointer and never steal an in-region GO/walk coordinate. */
.region-frame {
    display: inline-grid;
    grid-template-columns: auto auto auto;
    grid-template-rows: auto auto;
}
.region-frame .habitat-viewport { grid-column: 2; grid-row: 1; }
.edge-chevron {
    grid-row: 1;
    display: flex;
    align-items: center;
    justify-content: center;
    background: #15151c;
    color: #6cc0ff;
    border: none;
    padding: 0;
    font-size: 22px;
    line-height: 1;
    cursor: pointer;
    user-select: none;
}
.edge-chevron:hover { background: #24243a; color: #a9deff; }
.edge-chevron:active { background: #30304a; }
.edge-chevron.left  { grid-column: 1; width: 34px; }
.edge-chevron.right { grid-column: 3; width: 34px; }
.edge-chevron.down  { grid-column: 2; grid-row: 2; width: 100%; height: 34px; }
/* 3D perspective edge affordances: filled wedges over the black margins beside the floor plane. Only
   the filled polygons capture clicks (the SVG container is pointer-events:none), so in-region floor
   clicks fall through to the cursor overlay beneath. */
.edge-wedge {
    pointer-events: auto;
    cursor: pointer;
    fill: rgba(108, 192, 255, 0.10);
    transition: fill 0.1s;
}
/* A side is one selection: hovering EITHER pane (floor wedge or wall box) lights up both, so the
   neighbor floor+wall read as a single linked transit target. */
.edge-side:hover .edge-wedge { fill: rgba(108, 192, 255, 0.28); }
.edge-side:active .edge-wedge { fill: rgba(108, 192, 255, 0.40); }
.edge-wedge-glyph {
    pointer-events: none;
    fill: #6cc0ff;
    font-size: 22px;
    text-anchor: middle;
    dominant-baseline: central;
    opacity: 0.55;
}
.balloon-stage {
    position: relative;
    background: #000;
}
.balloon-panel {
    position: relative;
    z-index: 2;
    background: #000;
    overflow: hidden;
    flex-shrink: 0;
}
.balloon-panel-canvas {
    display: block;
    image-rendering: pixelated;
}
/* Webclient-only word-balloon scrollback bar — sits over the right edge / right chevron,
   in the C64 palette (set inline from c64Colors). Sharp, pixelated, no rounded corners. */
.balloon-scrollbar {
    position: absolute;
    top: 0;
    z-index: 3;
    image-rendering: pixelated;
    box-shadow: inset 1px 0 0 #000;
}
.balloon-scrollbar-thumb {
    position: absolute;
    left: 2px;
    right: 2px;
    cursor: grab;
    touch-action: none;
}
.balloon-scrollbar-thumb:active { cursor: grabbing; }

/* The original Habitat C64 character ROM as a web font (db/Text/charset). */
@font-face {
    font-family: "Habitat Charset";
    src: url("vendor/charset.woff2") format("woff2");
    font-display: swap;
}

/* Optional on-screen C64-style keyboard (onscreen-keyboard.mjs) for touch / kiosk clients.
   Synthesizes keydown events, so it's just a pad of buttons. Beige case + dark legends, chunky
   and pixelated to match the C64; modifier keys darker; an armed sticky modifier glows. */
/* Dock: the region-viewport width, centered in #app exactly like the region frame, so the keyboard
   lands directly UNDER the game. Centered (not flush-left) because open-terrain regions wrap the
   viewport in left/right edge chevrons (34px each) — the viewport is centered within that frame, so
   only a centered dock stays aligned with it whether or not the chevrons are present. (No max-width
   cap: #app's 16px padding would otherwise shrink it narrower than the region.) */
.osk-dock {
    align-self: center;
    width: calc(320px * 3);   /* the region viewport width (REGION_CANVAS_W * Scale) */
    display: flex;
    flex-direction: column;
    align-items: center;
}
.osk {
    display: flex;
    flex-direction: column;
    gap: 4px;
    padding: 6px;
    background: #2a2a36;
    border: 2px solid #15151c;
    border-radius: 4px;
    user-select: none;
    touch-action: none;
    width: 100%;
    /* No max-width cap: fill the .osk-dock, which is the region-viewport (client frame) width
       (320px * Scale). The keys are flex:1 1 0, so they stretch to span the whole frame; the
       larger key font below keeps the legends proportional to the now-frame-wide keys. */
}
.osk-row { display: flex; gap: 4px; justify-content: center; }
.osk-key {
    flex: 1 1 0;
    min-width: 0;
    min-height: 62px;
    padding: 8px 4px;
    font-family: "Habitat Charset", "Courier New", monospace;
    font-size: 33px;
    color: #2c2410;
    background: #c2b690;
    border: 1px solid #6f6450;
    border-top-color: #e6dcbd;
    border-left-color: #e6dcbd;
    border-radius: 3px;
    cursor: pointer;
    image-rendering: pixelated;
}
.osk-key:active { background: #a89c78; transform: translateY(1px); }
.osk-mod {
    background: #8a7c5c;
    color: #f0e8d2;
    flex-grow: 1.4;
    font-size: 19px;
    letter-spacing: 0.04em;
}
.osk-fkey { background: #9a6a4a; color: #f4e6da; font-size: 20px; }
.osk-active {  /* an armed single-use sticky modifier */
    background: #d9a521;
    color: #2c2410;
    box-shadow: 0 0 0 2px #ffe27a inset;
}
.osk-space { flex-grow: 6; }
.osk-return { flex-grow: 2.2; }
.osk-close { flex-grow: 0.8; }
.osk-arrows .osk-key { flex-grow: 0.6; }
.osk-toggle {
    align-self: flex-start;
    background: #15151c;
    color: #c2b690;
    border: 1px solid #3a3a4a;
    border-radius: 4px;
    padding: 4px 10px;
    font-size: 16px;
    cursor: pointer;
}
.osk-toggle:hover { background: #24243a; }
.balloon-graphics-band {
    position: relative;
    /* Above the balloon panel (2) and scrollbar (3). The quip sprite pokes UP out of this band
       into the panel's bottom edge (top: -QUIP_PANEL_OVERLAP_PX) and must paint over it, but a
       z-index:0 here would cap everything inside the band below the panel. Only the quip actually
       overlaps the panel — region graphics sit entirely below it — so lifting the whole band is
       safe and lets the quip win the overlap. */
    z-index: 4;
}
.balloon-quip {
    position: absolute;
    left: 0;
    top: 0;
    pointer-events: none;
    /* The quip tail points from the panel border at the speaker and must never be occluded — not
       by the panel above (handled by the band's z-index) nor by region object sprites within the
       band (z up to ~256, region.js). Sit above them, just below the cursor overlay (10000). */
    z-index: 9000;
}

/* C64 speak line (keyboard.m display_text_line) — below the 128px graphics band. */
.text-input-line {
    position: relative;
    z-index: 2;
    background: #fff;
    outline: none;
    cursor: text;
    flex-shrink: 0;
}
.text-input-line:focus {
    box-shadow: inset 0 0 0 1px #8e3c97;
}
.text-input-fallback {
    width: 100%;
    height: 100%;
    background: #fff;
}
.text-input-canvas {
    display: block;
    image-rendering: pixelated;
}

/* Inventory mode (Main/pick.m display_contents_screen) — replaces the region graphics
   band while a GET picks a noun from a container. 960×384 = 320×128 at scale 3. */
.inventory-stage {
    width: 960px;
    height: 384px;
    background: #14141c;
    color: var(--ink);
    display: flex;
    flex-direction: column;
}
.inventory-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    padding: 6px 12px;
    background: var(--panel);
    border-bottom: 1px solid var(--border);
    font-size: 14px;
}
.inv-abort {
    background: var(--accent);
    color: #08263f;
    border: 0;
    border-radius: 4px;
    padding: 4px 12px;
    font: inherit;
    font-weight: 600;
    cursor: pointer;
}
.inventory-grid {
    flex: 1;
    display: grid;
    grid-template-columns: repeat(var(--inv-cols, 4), 1fr);
    gap: 8px;
    padding: 12px;
    overflow: auto;
    align-content: start;
}
.inv-cell {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 4px;
    background: var(--panel);
    border: 1px solid var(--border);
    border-radius: 6px;
    padding: 8px;
    color: var(--ink);
    font: inherit;
    cursor: pointer;
}
.inv-cell:hover { border-color: var(--accent); background: #2e2e38; }
.inv-icon {
    display: grid;
    place-items: center;
    min-height: 56px;
    image-rendering: pixelated;
}
.inv-name { font-size: 11px; color: var(--muted); text-align: center; }
.inv-empty, .inv-loading { color: var(--muted); padding: 12px; }

/* Text display (Main/text_handler.m) — the canonical charset on a C64-pink page, with the
   Book_Menu prompt in the game font on white. Replaces the region graphics band. */
.text-stage {
    width: 960px;
    background: #14141c;
    color: var(--ink);
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 6px;
    padding: 6px 0;
}
.text-title { font-size: 13px; color: var(--muted); }
/* The pen cursor is the pointer over the page + menu (OS cursor hidden via inline
   cursor:none); page and menu stack inside this field, the caret floats over both. */
.text-field { position: relative; }
.text-canvas { display: block; image-rendering: pixelated; }
/* pen cursor (text_handler.m pen_icon, 2× the C64 sprite): typewriter-tip — an upward
   triangle at a char cell's bottom-center, pointing up at the character. */
.text-caret {
    position: absolute;
    width: 0;
    height: 0;
    border-left: 8px solid transparent;
    border-right: 8px solid transparent;
    border-bottom: 18px solid #1a1a1a;
    pointer-events: none;
}
.text-menu { image-rendering: pixelated; } /* NEXT BACK PAGE# QUIT — pen points at a zone */

/* Word balloon. Habitat balloons render in a text window at the TOP of the screen and
   hang downward, with a "quip" pointer (sprite) toward the speaker's x — see balloons.m.
   This is a faithful-in-spirit placement; the charset-glyph border and the speaker-tracking
   quip sprite are the real Main/balloons.m port in Phase 4. */
.balloon {
    position: absolute;
    left: 50%; top: 14px;            /* hangs from the top text window */
    transform: translateX(-50%);
    background: #fff;
    color: #000;
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
    font-size: 13px;
    text-align: center;
    padding: 8px 14px;
    border-radius: 12px;
    white-space: nowrap;
}
.balloon-tail {                      /* quip: points DOWN toward the speaker */
    position: absolute;
    left: 50%; top: 100%;
    transform: translateX(-50%);
    width: 0; height: 0;
    border: 8px solid transparent;
    border-top-color: #fff;
    border-bottom: 0;
}

/* MODE_CUSTOMIZE — the Hatchery customizer (lib/customize-view.js). The region renderer
   draws the Avatar (cursor frozen: no regionInput); the instruction panels render as the
   Avatar's own Habitat word balloons (custom.m draw_balloon_quip) via the game's balloon
   system, so the only style needed here is the stage wrapper. */
.customize-stage { position: relative; }
