/* Office OS shell. One typeface (PixelStartViet: 8 design px per em, line-height >= 1.5), hard shadows,
   no rounded corners, no blur. Colors are tokens; programs' windows use the same classes. */
@font-face { font-family: "PixelStartViet"; src: url("/fonts/pixelstartviet.ttf") format("truetype"); font-weight: 400; font-style: normal; font-display: swap; }
:root {
  --font: "PixelStartViet", ui-monospace, monospace;
  --bg: #1b1d2b; --bar: #12131d; --ink: #1e2030; --paper: #f8f8f0; --paper-2: #e8e6d8; --line: #2b2d42;
  --accent: #3868d8; --gold: #f8c838; --ok: #38b860; --warn: #e89830; --err: #d84848; --muted: #6b6f88; --soft: #9aa0c0;
}
* { box-sizing: border-box; -webkit-tap-highlight-color: transparent; }
html, body { margin: 0; height: 100%; background: var(--bg); color: var(--paper); overflow: hidden; }
body { font-family: var(--font); font-size: 10px; line-height: 1.6; display: flex; flex-direction: column;
  padding: env(safe-area-inset-top) env(safe-area-inset-right) env(safe-area-inset-bottom) env(safe-area-inset-left); }
button, input, textarea, select { font: inherit; color: inherit; }
[hidden] { display: none !important; }

/* top bar: start menu, open windows, tray, clock */
.bar { display: flex; align-items: center; gap: 8px; padding: 6px 8px; background: var(--bar); border-bottom: 3px solid #000; position: relative; z-index: 50; min-height: 44px; }
/* start button: the bar's own dark surface with the classic raised pixel bevel, pressed in while its menu is open */
.bar .start { display: inline-flex; align-items: center; gap: 6px; flex: none; background: var(--ink); color: var(--paper); border: 3px solid #000; padding: 4px 8px; font-size: 9px; line-height: 1.5; letter-spacing: 1px; cursor: pointer; box-shadow: inset 2px 2px 0 #4a4d62, inset -2px -2px 0 #0b0c14, 3px 3px 0 #000; }
.bar .start .flag { width: 14px; height: 14px; display: block; flex: none; }
.bar .start:focus-visible { outline: 2px solid var(--gold); outline-offset: 2px; }
.bar .start[aria-expanded="true"] { color: var(--gold); }
.bar .start[aria-expanded="true"], .bar .start:active { box-shadow: inset 2px 2px 0 #0b0c14, inset -2px -2px 0 #4a4d62, 1px 1px 0 #000; transform: translate(2px, 2px); }
.bar .tasks { display: flex; gap: 6px; overflow-x: auto; flex: 1; min-width: 0; scrollbar-width: none; }
.bar .tasks .btn { flex: none; }
.bar .tray { display: flex; gap: 10px; align-items: center; white-space: nowrap; }
.bar .clock { color: var(--soft); }
.bar .commit { color: var(--muted); font-size: 8px; }
.btn { background: var(--ink); color: var(--paper); border: 3px solid #000; box-shadow: inset 0 0 0 2px #3a3d50; padding: 6px 8px; cursor: pointer; white-space: nowrap; font-size: 9px; line-height: 1.5; }
.btn:active { transform: translate(1px, 1px); }
.btn[aria-pressed="true"], .btn.on { color: var(--gold); box-shadow: inset 0 0 0 2px var(--gold); }
.btn.light { background: var(--paper); color: var(--ink); border-color: var(--ink); box-shadow: 3px 3px 0 var(--ink); }
.btn.primary { background: var(--gold); color: var(--ink); border-color: var(--ink); box-shadow: 3px 3px 0 var(--ink); }
.btn.danger { background: var(--err); color: #fff; border-color: var(--ink); box-shadow: 3px 3px 0 var(--ink); }
.pill { display: inline-flex; align-items: center; gap: 6px; font-size: 9px; color: #cfd2e6; }
.pill i { width: 10px; height: 10px; display: inline-block; box-shadow: 0 0 0 2px #000; }
.pill.alert { color: #ff9a9a; } .pill.alert i { animation: blink .8s steps(2) infinite; }
@keyframes blink { 50% { opacity: .2; } }
@media (max-width: 640px) {
  .bar .clock, .bar .commit { display: none; }
  .bar .tasks { min-width: 80px; }
  .bar .tray { min-width: 0; max-width: 30%; overflow-x: auto; }
}

/* start menu: the classic frame on the bar's dark surface, a vertical OFFICE OS banner on the left, the
   programs on the right, and the agents submenu opening beside it (leftwards when the screen has no room) */
.menu { position: absolute; top: calc(100% + 2px); left: 8px; display: flex; align-items: stretch; background: var(--bar); color: var(--paper);
  border: 3px solid #000; box-shadow: inset 0 0 0 2px #3a3d50, 4px 4px 0 #000; min-width: 214px; max-height: min(70vh, 460px); z-index: 60; }
.menu .banner { flex: none; width: 24px; background: var(--accent); display: flex; align-items: flex-end; justify-content: center; padding: 8px 0; }
.menu .banner span { writing-mode: vertical-rl; transform: rotate(180deg); color: var(--paper); font-size: 9px; letter-spacing: 3px; white-space: nowrap; }
.menu .items { flex: 1; min-width: 0; overflow-y: auto; padding: 4px; display: flex; flex-direction: column; }
.menu .items button, .submenu button { display: flex; align-items: center; gap: 8px; width: 100%; text-align: left; background: none; border: 0; padding: 6px 8px; cursor: pointer; font-size: 9px; color: var(--paper); }
.menu .items button .ico, .submenu button .ico { flex: none; min-width: 16px; text-align: center; white-space: nowrap; }
.menu .items button .t, .submenu button .t { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.menu .items button .more { flex: none; color: var(--soft); }
.menu .items button:hover, .menu .items button:focus, .menu .items button[aria-expanded="true"],
.submenu button:hover, .submenu button:focus { background: var(--gold); color: var(--ink); outline: none; }
.menu .items button:hover .more, .menu .items button:focus .more, .menu .items button[aria-expanded="true"] .more { color: var(--ink); }
.submenu { position: absolute; z-index: 61; min-width: 190px; max-width: calc(100vw - 16px); max-height: min(60vh, 380px); overflow-y: auto; padding: 4px;
  display: flex; flex-direction: column; background: var(--bar); color: var(--paper); border: 3px solid #000; box-shadow: inset 0 0 0 2px #3a3d50, 4px 4px 0 #000; }
.submenu .subempty { margin: 0; padding: 6px 8px; font-size: 8px; color: var(--soft); white-space: nowrap; }

/* desktop: the office canvas */
.desk { flex: 1; position: relative; min-height: 0; overflow: hidden; }
.stage { position: absolute; inset: 0; touch-action: none; cursor: pointer; }
.stage canvas { position: absolute; inset: 0; width: 100%; height: 100%; display: block; image-rendering: pixelated; image-rendering: crisp-edges; }
.labels { position: absolute; inset: 0; pointer-events: none; overflow: hidden; }
/* speech bubble: 80% opaque paper so the words win over the room, with fully opaque ink text (FOR-636). The tail
   is three hard steps in the same paper with ink sides, tapering to the speaker's head. */
.labels .bubble { position: absolute; background: rgba(248, 248, 240, .8); color: var(--ink); border: 2px solid var(--ink); box-shadow: 2px 2px 0 #000;
  padding: 3px 6px; font-size: 8px; max-width: 180px; white-space: normal; text-align: center;
  /* the last 20% still lets a hint of the room through, so the glyphs keep their 1px paper ring for the edge cases */
  text-shadow: 1px 0 0 var(--paper), -1px 0 0 var(--paper), 0 1px 0 var(--paper), 0 -1px 0 var(--paper); }
.labels .bubble .tail { position: absolute; left: var(--tx, 50%); bottom: -9px; transform: translateX(-50%); display: flex; flex-direction: column; align-items: center; pointer-events: none; }
.labels .bubble .tail b { display: block; height: 3px; background: rgba(248, 248, 240, .8); border-left: 2px solid var(--ink); border-right: 2px solid var(--ink); }
.labels .bubble .tail b:nth-child(1) { width: 12px; }
.labels .bubble .tail b:nth-child(2) { width: 8px; }
.labels .bubble .tail b:nth-child(3) { width: 4px; }
.labels .bubble.below .tail { top: -9px; bottom: auto; flex-direction: column-reverse; }
/* names stay readable over any floor: a hard black plate at 60% behind fully opaque text (FOR-581) */
.labels .name { position: absolute; transform: translate(-50%, 0); font-size: 7px; color: var(--paper); background: rgba(0, 0, 0, .6); padding: 1px 2px; white-space: nowrap; }
.labels .name.sel { color: var(--gold); }
/* v0's plate colours: red when the agent needs you, green letters while it works */
.labels .name.need { color: #fff; background: rgba(200, 40, 40, .92); }
.labels .name.work { color: #9df5b8; }
.viewbar { position: absolute; right: 10px; bottom: 10px; z-index: 6; display: flex; gap: 6px; }
.boot { position: absolute; inset: 0; display: grid; place-items: center; color: var(--soft); background: var(--bg); z-index: 40; text-align: center; padding: 20px; }

/* retro screen (v0's CRT): v0's richer screen colours (saturation and contrast on the office canvas),
   scanlines every third pixel and a dark vignette over the office, with v0's slow flicker. Windows, the bar
   and the dock stay clear of it, and CRT off stays the natural palette. */
.crt { position: absolute; inset: 0; pointer-events: none; z-index: 5; display: none;
  background: repeating-linear-gradient(rgba(0,0,0,.22) 0 1px, transparent 1px 3px), radial-gradient(ellipse at center, transparent 58%, rgba(0,0,0,.55) 100%); }
body.crt-on .crt { display: block; animation: crtFlicker 4s steps(40) infinite; }
body.crt-on .stage canvas { filter: saturate(1.25) contrast(1.08); }
@keyframes crtFlicker { 0%, 100% { opacity: 1; } 3% { opacity: .86; } 6% { opacity: 1; } 48% { opacity: .95; } }
@media (prefers-reduced-motion: reduce) { body.crt-on .crt { animation: none; } }
.boot pre { font: inherit; text-align: left; white-space: pre-wrap; color: #cfd2e6; }
/* the boot console: an old machine starting up, full screen, top left, scrolling (os/boot.js) */
.boot { display: block; place-items: unset; text-align: left; background: #050608; padding: 14px 18px; }
.boot pre { margin: 0; height: 100%; overflow: hidden; font-size: 9px; line-height: 1.6; color: #b8bccc; }
.boot pre::after { content: "_"; animation: blink 1s steps(2) infinite; color: #e8ecf4; }
.boot .bl-ok { color: #58e878; } .boot .bl-err { color: #ff6a5a; } .boot .bl-hi { color: #ffffff; } .boot .bl-dim { color: #6b6f88; }
@media (max-width: 640px) { .boot pre { font-size: 7px; } }

/* dock: bars owned by programs (the news ticker …), under the office */
.dock { flex: none; display: flex; flex-direction: column; }
.dock:empty { display: none; }

/* windows */
.wins { position: absolute; inset: 0; pointer-events: none; z-index: 30; }
.win { position: absolute; pointer-events: auto; background: var(--paper); color: var(--ink); border: 3px solid var(--ink); box-shadow: 4px 4px 0 #000;
  display: flex; flex-direction: column; min-width: 240px; min-height: 120px; max-width: calc(100% - 8px); max-height: calc(100% - 8px); }
.win.focus { box-shadow: 4px 4px 0 #000, 0 0 0 2px var(--gold); }
.win .tb { display: flex; align-items: center; gap: 8px; background: var(--ink); color: var(--paper); padding: 6px 8px; cursor: move; user-select: none; touch-action: none; }
.win .tb .t { flex: 1; font-size: 9px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.win .tb button { background: var(--paper); color: var(--ink); border: 2px solid #000; width: 22px; height: 22px; padding: 0; cursor: pointer; font-size: 9px; line-height: 1; }
.win .wb { flex: 1; overflow: auto; padding: 10px; min-height: 0; font-size: 9px; }
.win .wb.flush { padding: 0; }
.win .resize-grip { position: absolute; right: 0; bottom: 0; width: 20px; height: 20px; padding: 0; border: 0; cursor: nwse-resize; touch-action: none; background: var(--ink); }
.win .resize-grip::after { content: ''; position: absolute; right: 3px; bottom: 3px; width: 4px; height: 4px; background: var(--paper); box-shadow: -5px 0 var(--paper), 0 -5px var(--paper); }
.win .resize-grip:focus-visible { outline: 2px solid var(--gold); outline-offset: -2px; }
@media (max-width: 640px) {
  /* a phone shows one window as a bottom sheet over most of the screen: 80-90% of the screen's height (85% when
     it opens, the grip resizes it inside that range), never past the top of the office area */
  .win { left: 4px !important; right: 4px; width: auto !important; top: auto !important; bottom: 4px;
    min-height: min(80dvh, calc(100% - 8px)); max-height: min(90dvh, calc(100% - 8px)); }
  .win .tb { cursor: default; padding-left: 28px; }
  .win .resize-grip { left: 0; right: auto; top: 0; bottom: auto; cursor: ns-resize; }
}

/* shared widgets for app windows */
.row { display: flex; gap: 8px; align-items: center; }
.stack { display: flex; flex-direction: column; gap: 8px; }
.muted { color: var(--muted); }
.tag { display: inline-block; padding: 1px 4px; border: 2px solid var(--ink); font-size: 7px; }
.field { width: 100%; border: 3px solid var(--ink); background: #fff; padding: 8px; font-size: 10px; line-height: 1.6; }
textarea.field { resize: vertical; min-height: 60px; }
/* iOS Safari and Chrome on Android zoom the page when a focused text control's font size is under 16px.
   Touch devices get 16px controls so focusing one never zooms; the pixel sizes stay on desktop pointers.
   Pinch zoom still works: index.html's viewport meta sets no maximum-scale. Programs set their own smaller
   sizes for the pixel look, so this rule overrides them. Checkboxes, radios, files, ranges and colours are
   not text entry and keep their sizes. */
@media (pointer: coarse) {
  input:not([type="checkbox"]):not([type="radio"]):not([type="file"]):not([type="range"]):not([type="color"]):not([type="hidden"]),
  textarea, select { font-size: 16px !important; }
}
table.grid { width: 100%; border-collapse: collapse; font-size: 8px; }
table.grid th, table.grid td { text-align: left; padding: 4px 6px; border-bottom: 2px solid var(--paper-2); white-space: nowrap; }
table.grid th { color: var(--muted); font-weight: 400; position: sticky; top: 0; background: var(--paper); }
table.grid tr.bad td { color: var(--err); }
.term { background: #0c0d14; color: #c8f0c8; font-size: 9px; line-height: 1.6; padding: 8px; white-space: pre-wrap; overflow-y: auto; flex: 1; min-height: 0; }
.term .err { color: #ff8a8a; } .term .cmd { color: var(--gold); }
.term-in { display: flex; background: #0c0d14; border-top: 2px solid #2b2d42; }
.term-in span { color: var(--gold); padding: 8px 0 8px 8px; }
.term-in input { flex: 1; background: none; border: 0; color: #fff; padding: 8px; outline: none; }
.chat { display: flex; flex-direction: column; gap: 6px; }
.msg { padding: 6px 8px; border: 2px solid var(--ink); max-width: 90%; white-space: pre-wrap; word-break: break-word; }
.msg.me { align-self: flex-end; background: #dfe8ff; }
.msg.them { align-self: flex-start; background: #fff; }
.msg.sys { align-self: center; border-style: dashed; color: var(--muted); }

/* toasts */
.toasts { position: absolute; left: 50%; top: 10px; transform: translateX(-50%); display: flex; flex-direction: column; gap: 6px; z-index: 45; pointer-events: none; align-items: center; }
.toast { background: var(--ink); color: var(--paper); border: 3px solid #000; box-shadow: 3px 3px 0 #000; padding: 6px 10px; font-size: 9px; max-width: min(520px, 90vw); }
.toast.err { color: #ff9a9a; }
/* voice typing (core.voice/typing.js): the microphone on the focused text field */
.vmic { position: fixed; z-index: 75; width: 30px; height: 30px; border: 3px solid var(--ink); background: var(--paper); box-shadow: 2px 2px 0 var(--ink); font-size: 13px; cursor: pointer; display: flex; align-items: center; justify-content: center; padding: 0; color: var(--ink); }
.vmic:focus-visible { outline: 3px solid var(--accent); outline-offset: 1px; }
.vmic.rec { background: #e84848; color: #fff; animation: vmic-blink 1s steps(2) infinite; }
.vmic.busy { background: var(--gold); }
@keyframes vmic-blink { 50% { opacity: 0.4; } }
/* the task banner: slides down from the top, a frame in the event's colour, tap opens the task */
.tbanner { --bn: var(--gold); position: absolute; left: 50%; top: 10px; z-index: 46; width: min(520px, calc(100% - 20px)); transform: translate(-50%, calc(-100% - 30px));
  background: var(--ink); color: var(--paper); border: 4px solid #000; box-shadow: inset 0 0 0 3px var(--bn), 4px 4px 0 rgba(0,0,0,.5); padding: 10px 14px;
  display: block; text-align: left; font: inherit; cursor: default; transition: transform .25s steps(5); pointer-events: none; }
.tbanner.show { transform: translate(-50%, 0); pointer-events: auto; }
.tbanner.link { cursor: pointer; }
.tbanner > b { display: block; font-size: 9px; line-height: 1.5; color: var(--bn); margin-bottom: 4px; font-weight: normal; }
.tbanner > b .px-ico-w { font-size: 16px; vertical-align: -5px; margin-right: 4px; }
.tbanner > span { font-size: 10px; line-height: 1.5; overflow: hidden; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; }
@media (prefers-reduced-motion: reduce) { .tbanner { transition: none; } }
/* the title card (v0's theme intro): a gold-framed card in the middle of the office, tap to dismiss or act */
.titlecard { position: absolute; left: 50%; top: 40%; transform: translate(-50%, -50%); z-index: 47; width: min(420px, calc(100% - 24px));
  background: var(--ink); color: var(--paper); border: 4px solid #000; box-shadow: inset 0 0 0 3px var(--gold), 8px 8px 0 rgba(0,0,0,.5);
  padding: 18px 22px; display: grid; gap: 10px; text-align: center; font: inherit; cursor: pointer; transition: opacity .35s steps(4); }
.titlecard[hidden] { display: none; }
.titlecard.out { opacity: 0; }
.titlecard > span { font-size: 8px; line-height: 1.5; color: #9aa0c0; }
.titlecard > b { font-size: 12px; line-height: 1.5; color: var(--gold); font-weight: normal; letter-spacing: 1px; }
.titlecard > small { font-size: 8px; line-height: 1.6; color: #c8ccd8; }
.titlecard > em { font-style: normal; font-size: 8px; line-height: 1.5; color: #58e088; animation: blink 1s steps(2) infinite; }
@media (prefers-reduced-motion: reduce) { .titlecard { transition: none; } .titlecard > em { animation: none; } }

/* 3D view: its own controls sit over the canvas */
.r3d-walkbtn { position: absolute; right: 10px; bottom: 48px; z-index: 7; }
.r3d-followbtn { position: absolute; right: 76px; bottom: 48px; z-index: 7; }
.stage canvas.r3d-minimap { position: absolute; inset: auto; left: 10px; top: 10px; width: 150px; height: 80px; display: block; box-sizing: content-box; background: #000; outline: 3px solid #000; box-shadow: inset 0 0 0 2px #3a3d50; image-rendering: pixelated; image-rendering: crisp-edges; cursor: crosshair; touch-action: none; }
.stage canvas.r3d-minimap[hidden] { display: none; }
.r3d-tint { pointer-events: none; z-index: 3; }
.r3d-hint { position: absolute; left: 10px; bottom: 10px; z-index: 7; background: none; border: 0; color: var(--paper); text-shadow: 1px 1px 0 #000, -1px 1px 0 #000, 1px -1px 0 #000, -1px -1px 0 #000; font-size: 8px; cursor: pointer; }
.r3d-pad { position: absolute; right: 12px; bottom: 88px; z-index: 7; display: grid; grid-template-columns: repeat(3, 34px); grid-template-rows: repeat(2, 34px); gap: 4px; }
.r3d-pad .btn { padding: 0; font-size: 10px; }
.r3d-pad .btn[data-w="f"] { grid-column: 2; grid-row: 1; }
.r3d-pad .btn[data-w="l"] { grid-column: 1; grid-row: 2; }
.r3d-pad .btn[data-w="b"] { grid-column: 2; grid-row: 2; }
.r3d-pad .btn[data-w="r"] { grid-column: 3; grid-row: 2; }
@media (max-width: 640px) {
  .stage canvas.r3d-minimap { width: 112px; height: 60px; }
  .r3d-followbtn { right: 70px; }
}

/* drawn pixel icons in text (os/shell/icons.js): one em tall, in the text's colour, sitting on the baseline */
.px-ico-w { display: inline-flex; vertical-align: -0.12em; }
.px-ico { display: block; width: 1em; height: 1em; }

/* the view-only office: no OFFICE start button (nothing to launch) and no hand cursor on people you cannot open */
body.view-only .bar .start { display: none; }
body.view-only .bar .view-tag { display: none; }
