/* core.css -- the tokens and the shell of the browser client.
 *
 * THE TOKENS ARE THE STUDIO'S OWN (src/ui/tokens.wz dark and light, src/ui/lexcol.wz),
 * as CSS variables; a module uses var(--surface), never a hex of its own. WHERE THE
 * TOKENS AND VS CODE DIFFER, VS CODE WINS (localfiles/webclient/BRIEFING.md) -- the
 * metrics below (35px title bar, 48px activity bar, 22px status bar, 35px tabs) are
 * VS Code's, and a deliberate deviation from a token is noted where it is made.
 *
 * THEMES: dark is the default; light follows the OS (prefers-color-scheme) unless
 * <html data-theme="dark"|"light"> forces one (e5b). Everything is a variable, so a
 * theme is one block.
 *
 * LAYOUT: one CSS grid for the app, one for the body. The sidebar collapses with
 * body.nosidebar, the bottom panel opens with body.panelopen; widths are variables so a
 * splitter (e5b) sets them without touching this file.
 */

:root {
  color-scheme: dark;       /* native controls (select, scrollbars, checkboxes) follow the theme */
  /* ---- dark theme, src/ui/tokens.wz ---- */
  --bg:          #1e1e1e;   /* UI_BG */
  --surface:     #252926;   /* UI_SURFACE */
  --surface2:    #303030;   /* UI_SURFACE2 */
  --rule:        #424242;   /* UI_RULE */
  --text-strong: #f0f0f0;   /* UI_TEXTSTRONG */
  --text:        #c8d0d4;   /* UI_TEXT */
  --text-dim:    #858585;   /* UI_TEXTDIM */
  --text-muted:  #666666;   /* UI_TEXTMUTED */
  --accent:      #0e5f9c;   /* UI_ACCENT */
  --accent-hi:   #127cbd;   /* UI_ACCENTHI */
  --accent-tx:   #ffffff;   /* UI_ACCENTTX */
  --danger:      #d43333;   /* UI_DANGER */
  /* ERROR TEXT is not --danger: dark red on a dark background was hard to read (the author,
     24-09-2026: "fel-geel misschien handiger"). Red stays for areas, dots and borders. */
  --danger-tx:   #ffd84a;
  --ok:          #3a9d43;   /* UI_OK */
  --attn:        #d9a441;   /* UI_ATTN */
  --chrome:      #333333;   /* UI_CHROME */
  --statusbg:    #007ecc;   /* UI_STATUSBG */
  --curline:     #242c28;   /* UI_CURLINE */
  --indent:      #404040;   /* UI_INDENT */
  --selection:   #264f78;   /* VS Code editor.selectionBackground; no token for it yet */
  --hover:       #2a2d2e;   /* VS Code list.hoverBackground */
  --focus:       #007fd4;   /* VS Code focusBorder */

  /* Shared work surfaces: quiet warm chrome, with the editor canvas retaining its
     separate dark tokens. These are shell-only tokens; feature modules inherit them. */
  --work-chrome: #252926;
  --work-surface: #303030;
  --work-rule: #424242;
  --work-accent: #0e5f9c;

  /* ---- syntax, src/ui/tokens.wz dark ---- */
  --syn-keyword: #c58ac0;
  --syn-type:    #56a0d6;
  --syn-ident:   #dcdcaa;
  --syn-const:   #4ec7b0;
  --syn-comment: #6a9955;   /* VS Code Dark+ (officieel); tokens.wz droeg #559955, BESLUITEN-FASE-B.md 23-09-2026: VS Code wint */
  --syn-string:  #ce9178;
  --syn-number:  #b5cea8;

  /* ---- metrics: VS Code's ---- */
  /* DE HOOGTES GROEIEN MEE MET --ui-fs: VS Code's 35/22 bij 13 px tekst, hier
     bij 17 px -> 46/29. e5b.js zet ze opnieuw als editor.panelsize verandert (round(35 * v / 13),
     round(22 * v / 13)); e3a.js en e8c.js lezen --row-h als getal, dus ze blijven px. */
  --title-h:    46px;
  --status-h:   29px;
  --tab-h:      46px;
  --row-h:      29px;
  /* 19 PX CODE, 17 PX PANELEN (the author 28-09-2026, bewust groter dan VS Code's
     14/13). De regelhoogte volgt VS Code's eigen verhouding (19 bij 14 px) -> 26 px. Dezelfde
     getallen staan als standaard van editor.fontsize/editor.panelsize in cfgmodel.wz, en
     e5b.js past een instelling toe met die verhouding -- houd de drie gelijk. */
  --line-h:     26px;
  --code-fs:    19px;
  --ui-fs:      17px;
  --side-w:     260px;
  --panel-h:    220px;

  --font-ui:   "Segoe UI", system-ui, -apple-system, "DejaVu Sans", sans-serif;
  --font-code: "Cascadia Mono", "Consolas", "DejaVu Sans Mono", ui-monospace, monospace;

  /* ---- shape and elevation: dark keeps the sharp, bordered VS Code look (2-4px, no
     shadow) as its default; the light theme below redefines all three to the calmer,
     rounded, shadow-based look of. A component asking for "a dialog's
     radius" writes --radius-lg, not a literal number, so light and dark can each answer
     it differently without every component's own CSS changing. ---- */
  --radius-sm:   3px;   /* a button, an input, a small chip -- current VS Code-ish value */
  --radius-md:   4px;   /* a dropdown, a menu, a small card */
  --radius-lg:   6px;   /* a dialog, a big panel */
  --shadow-card: 0 2px 8px rgba(0,0,0,.36);  /* the current flat drop-shadow */
  --surface-card: var(--surface);            /* a floating card (menu, dialog, palette) */
}

* { box-sizing: border-box; }
/* hidden wint ALTIJD. De kern verbergt zijbalkviews en panelen met het hidden-attribuut;
   een module die zijn view display: flex geeft (e8a deed dat) overschreef dat, en dan
   stond die lege view permanent open en duwde elk ander paneel uit beeld. */
[hidden] { display: none !important; }

html, body {
  margin: 0; padding: 0; height: 100%;
  /* clip, niet alleen hidden: hidden verbiedt de gebruiker het scrollen, maar
     scrollIntoView scrolde body toch 13px mee zodra iets absoluut geplaatsts eronder
     uitstak -- de menubalk viel dan half van het scherm. clip verbiedt het ook in code. */
  overflow: hidden;
  overflow: clip;
  background: var(--chrome);
  color: var(--text);
  font: var(--ui-fs)/1.4 var(--font-ui);
  -webkit-user-select: none; user-select: none;
}
button { font: inherit; color: inherit; background: none; border: 0; padding: 0; cursor: pointer; }
button:focus-visible { outline: 1px solid var(--focus); outline-offset: -1px; }

/* ---- APP GRID ------------------------------------------------------------------ */
#app {
  height: 100%;
  display: grid;
  grid-template-rows: var(--title-h) 1fr var(--status-h);
  /* NEVER WIDER THAN THE WINDOW. Without this the single column grows with the widest
     unbreakable content -- a long status message pushed the whole page past the right edge. */
  grid-template-columns: minmax(0, 1fr);
}

/* ---- TITLE / MENU BAR ----------------------------------------------------------- */
#titlebar {
  display: flex; align-items: center; gap: 4px;
  padding: 0 8px;
  background: var(--work-chrome);
  border-bottom: 1px solid var(--work-rule);
  color: var(--text-strong);
  font-size: calc(var(--ui-fs) * 12 / 13);
}
#titlebar .logo { color: var(--work-accent); display: flex; margin-right: 6px; }
#titlebar .title { font-weight: 400; color: var(--text-dim); }
.spacer { flex: 1; }
.badge {
  font-size: calc(var(--ui-fs) * 11 / 13); padding: 2px 8px; border-radius: 10px;
  background: var(--surface2); color: var(--text-dim);
}
.badge[data-state="ok"]   { background: #14351c; color: var(--ok); }
.badge[data-state="gone"] { background: #3a1a1a; color: var(--danger-tx); }

#menubar { display: flex; align-items: stretch; height: 100%; }
#menubar .menu {
  position: relative;
  padding: 0 8px; border-radius: 4px; height: 22px; align-self: center;
  color: var(--text);
}
#menubar .menu:hover, #menubar .menu.open { background: var(--surface2); color: var(--text-strong); }
#menubar .dropdown {
  position: absolute; top: 100%; left: 0; z-index: 50;
  min-width: 220px; padding: 4px 0; margin-top: 2px;
  background: var(--surface); border: 1px solid var(--rule); border-radius: 5px;
  box-shadow: 0 4px 12px rgba(0,0,0,.35);
  text-align: left; cursor: default;
}
#menubar .dropdown .item {
  display: flex; align-items: center; gap: 24px;
  padding: 0 10px 0 26px; height: 26px; margin: 0 4px; border-radius: 4px;
  color: var(--text); white-space: nowrap;
}
#menubar .dropdown .item .label { flex: 1; }
#menubar .dropdown .item .key { color: var(--text-dim); font-size: calc(var(--ui-fs) * 11 / 13); }
#menubar .dropdown .item:hover:not(.disabled) { background: var(--accent); color: var(--accent-tx); }
#menubar .dropdown .item:hover:not(.disabled) .key { color: var(--accent-tx); }
#menubar .dropdown .item.disabled { color: var(--text-muted); }
#menubar .dropdown .sep { height: 1px; margin: 4px 10px; background: var(--rule); }
/* ---- BODY GRID ------------------------------------------------------------------ */
#body {
  display: grid;
  grid-template-columns: var(--side-w) 1px 1fr;
  min-height: 0;
}
body.nosidebar #body { grid-template-columns: 0 0 1fr; }
body.nosidebar #sidebar, body.nosidebar #sidesplit { display: none; }
body.nosidebar #main { grid-column: 3; }              /* the two hidden columns hold no cell: without this #main fell into the 0 px column */

/* ---- SIDE BAR: the Explorer only ----------------------------------- */
#sidebar {
  background: var(--work-chrome);
  display: flex; flex-direction: column;
  min-width: 0; min-height: 0;
}
.panelhead {
  height: var(--tab-h); padding: 0 20px;
  display: flex; align-items: center;
  font-size: calc(var(--ui-fs) * 11 / 13); text-transform: uppercase; letter-spacing: .04em;
  color: var(--text-dim);
}
#sideswitch { display: none; gap: 12px; }
body.sidemulti #sidebar .panelhead { padding: 0 12px; }
body.sidemulti #sidetitle { display: none; }
body.sidemulti #sideswitch { display: flex; min-width: 0; height: 100%; overflow-x: auto; scrollbar-width: none; }   /* four tabs do not fit 260 px: the strip scrolls */
#sideswitch::-webkit-scrollbar { display: none; }
.stab { flex: none; }
.stab {
  background: none; border: 0; border-bottom: 2px solid transparent; padding: 0; height: 100%;
  font: inherit; text-transform: inherit; letter-spacing: inherit; color: var(--text-dim); cursor: pointer;
}
.stab:hover { color: var(--text); }
.stab.on { color: var(--text-strong); border-bottom-color: var(--focus); }
#sideviews { flex: 1; min-height: 0; overflow: auto; }
.sideview { height: 100%; }

.split { background: var(--rule); position: relative; }
.split[aria-orientation="vertical"] { cursor: col-resize; }
.split[aria-orientation="horizontal"] { cursor: row-resize; height: 1px; }
.split::after { content: ""; position: absolute; inset: 0 -3px; }
.split[aria-orientation="horizontal"]::after { inset: -3px 0; }
.split:hover, .split.drag { background: var(--focus); }
/* a divider inside a flex row (the Tickets list, the agents list): same look as the others, made by S.splitter.attach; a phone has none */
.colsplit { flex: 0 0 1px; align-self: stretch; touch-action: none; }
@media (max-width: 760px) { .colsplit { display: none; } }

/* ---- EDITOR GROUP ----------------------------------------------------------------- */
#main {
  background: var(--bg);
  display: grid;
  grid-template-rows: var(--tab-h) 1fr 0 0;
  min-width: 0; min-height: 0;
}
body.panelopen #main { grid-template-rows: var(--tab-h) 1fr 1px var(--panel-h); }
#panelsplit, #panel { display: none; }
body.panelopen #panelsplit { display: block; }
/* #panel is een grid (35px kop + 1fr inhoud, zie verderop); "display: block" hier zou die
 * grid overschrijven, #panelviews groeit dan ongeclipt met zijn inhoud mee en een lange
 * inhoud (het nieuw-profiel-formulier) zakt uit het paneel EN de viewport. */
body.panelopen #panel { display: grid; }
/* MAXIMIZE PANEL SIZE: the panel takes the whole editor-group row, like VS
 * Code's chevron-in-the-corner. #tabs/#editor/#panelsplit are hidden rather than sized to
 * 0 -- an editor at 0 height still has to lay out its gutter and viewport, and giving it
 * nothing to measure is simpler than trusting it degrades gracefully at zero. */
body.panelopen.panelmax #main { grid-template-rows: 0 0 0 1fr; }
body.panelopen.panelmax #tabs, body.panelopen.panelmax #editor, body.panelopen.panelmax #panelsplit { display: none; }
/* THE PANEL KEEPS ROW 4 WHEN THE OTHERS ARE GONE: an element with display:none takes no grid
 * cell, so without this #panel was auto-placed into row 1 -- the 0 px one -- and every
 * maximized panel showed nothing (measured: #panel 1179x0). */
body.panelopen.panelmax #panel { grid-row: 4; }

#tabs {
  display: flex; align-items: stretch;
  background: var(--work-chrome);
  overflow-x: auto; overflow-y: hidden;
  scrollbar-width: none;
}
#editor { position: relative; min-height: 0; overflow: hidden; }

/* ---- BOTTOM PANEL ------------------------------------------------------------------ */
/* NO display HERE: body.panelopen #panel sets grid, and a closed panel is display:none (above).
 * This rule used to say display:grid too, and being later it won -- a closed panel kept its
 * tab row, drawn over the status bar (seen once simple mode started with the panel closed). */
#panel { background: var(--bg); grid-template-rows: 35px 1fr; min-height: 0; }
#paneltabs {
  display: flex; align-items: center; gap: 16px; padding: 0 8px 0 20px;
  border-bottom: 1px solid var(--rule);
  /* MANY TABS NOW (every former sidebar feature lives here): scroll the strip rather
   * than shrink it and lose readability, same choice as #tabs above it. */
  overflow-x: auto; overflow-y: hidden; scrollbar-width: none;
}
.ptab {
  font-size: calc(var(--ui-fs) * 11 / 13); text-transform: uppercase; letter-spacing: .04em;
  color: var(--text-dim); height: var(--tab-h); border-bottom: 1px solid transparent;
  white-space: nowrap; flex: 0 0 auto;
}
/* hover gebruikte --text-strong, exact dezelfde kleur als .ptab.on -- een
 * cursor die toevallig boven een NIET-actieve tab bleef staan (bv. net na een klik
 * ernaast) maakte die tab even zo wit als de echt actieve, en op een schermafbeelding
 * lijken dat dan TWEE actieve tabs. Hover krijgt nu een tussenkleur (--text, dimmer dan
 * --text-strong) en geen onderstreep, zodat alleen .on ooit de volle --text-strong +
 * lijn combinatie draagt -- dezelfde scheiding als VS Code's inactive-tab-hover
 * tegenover zijn active-tab-foreground. */
.ptab:hover { color: var(--text); }
.ptab.on { color: var(--text-strong); border-bottom-color: var(--text-strong); }
.ptab.on:hover { color: var(--text-strong); }
#panelviews { min-height: 0; overflow: auto; }
.panelview { height: 100%; }

/* THE CORNER OF THE PANEL: maximize/restore and hide, pinned to the right of the tab
 * strip. The strip SCROLLS when there are many tabs (full mode has eleven), and the buttons used to
 * scroll with it -- off the screen below ~1400 px. Sticky keeps them in view, with the panel's own
 * background so the tabs pass underneath. order: the corner is the strip's FIRST child (index.html)
 * and the tabs are appended after it; without order it pushed every tab to the right. */
#panelcorner {
  order: 99; margin-left: auto; flex: 0 0 auto;
  position: sticky; right: 0; z-index: 1;
  display: flex; align-items: center; gap: 2px;
  padding-left: 8px; background: var(--bg);
}
#panelmaxbtn, #panelclosebtn {
  width: 22px; height: 22px;
  display: flex; align-items: center; justify-content: center;
  color: var(--text-dim); border-radius: 4px;
}
#panelmaxbtn:hover, #panelclosebtn:hover { color: var(--text-strong); background: var(--hover); }

/* ---- STATUS BAR -------------------------------------------------------------------- */
#status {
  display: flex; align-items: center;
  background: var(--work-chrome); color: var(--text-dim);
  border-top: 1px solid var(--work-rule);
  font-size: calc(var(--ui-fs) * 12 / 13); padding: 0 10px 0 0;
}
#status { min-width: 0; overflow: hidden; }
#status-left, #status-right { display: flex; align-items: center; height: 100%; }
/* a long message on the left is clipped; the right side (cursor, language) always stays whole */
#status-left { min-width: 0; overflow: hidden; flex: 0 1 auto; }
#status-right { flex: 0 0 auto; }
.stitem { display: flex; align-items: center; height: 100%; padding: 0 5px; white-space: nowrap; min-width: 0; overflow: hidden; }
.stitem:hover { background: rgba(255,255,255,.12); }
#status-left .stitem:first-child { padding-left: 10px; }

/* ---- CONNECTION LOST ------------------------------------------------------------- */
#gone {
  position: fixed; inset: 0; z-index: 100;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  background: var(--bg); color: var(--text);
}
#gone[hidden] { display: none; }
#gone svg { width: 64px; height: 64px; }
#gone h1 { font-size: calc(var(--ui-fs) * 20 / 13); font-weight: 600; margin: 16px 0 6px; color: var(--text-strong); }
#gone p { margin: 0; color: var(--text-dim); }

/* ---- scrollbars, VS Code-like ------------------------------------------------------ */
::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-thumb { background: rgba(121,121,121,.4); }
::-webkit-scrollbar-thumb:hover { background: rgba(100,100,100,.7); }
::-webkit-scrollbar-track { background: transparent; }

/* ---- columns you can drag. One grip on the right edge of a header cell; the line is
 * the seam colour at rest and the focus colour while it is hovered, focused or dragged. A list
 * nobody resized keeps its automatic widths: only a resized table gets table-layout: fixed. */
.colh { position: relative; }
.colgrip { position: absolute; top: 0; right: 0; width: 8px; height: 100%; cursor: col-resize; touch-action: none; z-index: 2; -webkit-user-select: none; user-select: none; }
.colgrip::after { content: ""; position: absolute; right: 3px; top: 20%; height: 60%; width: 1px; background: var(--rule); }
.colgrip:hover::after, .colgrip:focus-visible::after, .colgrip.drag::after { background: var(--focus); width: 2px; right: 2px; top: 10%; height: 80%; }
.colgrip:focus-visible { outline: none; }
table.cols-fixed { table-layout: fixed; max-width: none; }
table.cols-fixed th, table.cols-fixed td { overflow: hidden; overflow-wrap: anywhere; }
table.cols-fixed th { text-overflow: ellipsis; }
.colgrip-pane { top: 0; bottom: 0; right: -4px; width: 8px; height: auto; }
.colgrip-pane::after { right: 3px; top: 0; height: 100%; }

/* the mode switch: three positions, the current one marked */
.modeswitch .modeseg { padding: 0 6px; cursor: pointer; opacity: .75; }
.modeswitch .modeseg:hover { opacity: 1; text-decoration: underline; }
.modeswitch .modeseg.on { opacity: 1; font-weight: 600; cursor: default; text-decoration: none; border-bottom: 2px solid currentColor; }

/* a new release was rolled out while this tab was open: one bar, no reload of its own */
#newrelease { position: fixed; left: 50%; bottom: 34px; transform: translateX(-50%); z-index: 9000; display: flex; gap: 12px; align-items: center;
  padding: 8px 14px; border-radius: 6px; background: var(--accent); color: var(--accent-tx); font-size: 13px; box-shadow: 0 2px 10px rgba(0,0,0,.35); }
#newrelease button { background: var(--accent-tx); color: var(--accent); border: 0; border-radius: 4px; padding: 3px 10px; font: inherit; cursor: pointer; }
