/* One visual language for every web surface.
   Modelled on the Azure portal: a top bar that never moves, a left rail that
   lists the whole product, and a blade with a breadcrumb, a title and a command
   bar above its content. Everything is a token, so a surface never picks a
   colour — it picks a role. */
:root {
  color-scheme: dark;

  --accent:        #4c8dff;   /* the one interactive colour */
  --accent-strong: #2f6fe0;
  --accent-soft:   #1b2a47;

  --bg:            #0b0d12;   /* page */
  --bg-raised:     #11141c;   /* rail, top bar */
  --bg-card:       #161a24;   /* cards, rows, inputs */
  --bg-hover:      #1d2331;

  --line:          #262c3a;
  --line-strong:   #38405a;

  --text:          #e8ebf5;
  --text-soft:     #9aa3ba;
  --text-faint:    #6b7488;

  --ok:            #4fd08a;
  --warn:          #e8b563;
  --danger:        #ff8189;
  --danger-bg:     #2c1a1e;
  --danger-line:   #5c2f38;

  --phone:         640px;   /* documented here; media queries cannot read a custom property */
  --radius:        6px;
  --radius-lg:     10px;
  --rail-width:    248px;
  --topbar-height: 48px;

  font-family: "Segoe UI", Inter, system-ui, -apple-system, sans-serif;
  font-size: 14px;
  background: var(--bg);
  color: var(--text);
}
* { box-sizing: border-box; }
body { margin: 0; }
a { color: var(--accent); }

/* ---------- top bar ---------- */
.topbar {
  position: sticky; top: 0; z-index: 40;
  display: flex; align-items: center; gap: 12px;
  height: var(--topbar-height); padding: 0 12px;
  background: var(--bg-raised); border-bottom: 1px solid var(--line);
}
.brand { font-weight: 600; font-size: 15px; color: var(--text); text-decoration: none; letter-spacing: .01em; }
/* The rail toggle. It had no rule at all — a bare browser button in the top bar,
   in the browser's own grey, since the frame was written. */
.icon-button {
  display: inline-grid; place-items: center;
  width: 30px; height: 30px; padding: 0;
  background: transparent; color: var(--text-soft);
  border: 1px solid transparent; border-radius: var(--radius);
  font-size: 15px; line-height: 1; cursor: pointer;
}
.icon-button:hover { background: var(--bg-hover); color: var(--text); }
.icon-button:focus-visible { outline: 2px solid var(--accent); outline-offset: -1px; }
.spacer { flex: 1; }
.account { display: flex; align-items: center; gap: 10px; font-size: 13px; color: var(--text-soft); }
.avatar { width: 26px; height: 26px; border-radius: 50%; object-fit: cover; }
.avatar.initials {
  display: grid; place-items: center; background: var(--accent-soft);
  color: var(--accent); font-size: 11px; font-weight: 600;
}
.account-name { max-width: 18ch; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.signout { font-size: 12px; text-decoration: none; }
.signout:hover { text-decoration: underline; }

/* ---------- layout ---------- */
.portal { display: grid; grid-template-columns: var(--rail-width) 1fr;
  min-height: calc(100vh - var(--topbar-height)); }
/* A surface whose content IS the page — a conversation, a canvas — needs a
   height it can divide, not a minimum it can exceed. The chain runs unbroken
   from here to the surface's own container; `min-height: 0` at every step is
   what stops a flex child from refusing to shrink below its content. */
.portal.fill { height: calc(100vh - var(--topbar-height)); }
.portal.collapsed { grid-template-columns: 0 1fr; }
/* Never a grid item: without this it would take the second column and push the
   blade into a row of its own. It only becomes anything at all on a phone. */
.rail-scrim { display: none; }
.portal.collapsed .rail { display: none; }

/* ---------- left rail ---------- */
.rail {
  background: var(--bg-raised); border-right: 1px solid var(--line);
  padding: 8px 0; overflow-y: auto;
  position: sticky; top: var(--topbar-height); height: calc(100vh - var(--topbar-height));
}
.rail-group + .rail-group { margin-top: 2px; }
.rail-head {
  display: flex; align-items: center; gap: 10px;
  padding: 8px 14px; color: var(--text-soft); text-decoration: none;
  font-size: 13px; border-left: 3px solid transparent;
}
.rail-head { color: var(--text); font-weight: 600; }
.rail-head:hover { background: var(--bg-hover); color: var(--text); }
.rail-head.current { border-left-color: var(--accent); background: var(--bg-hover); }
.rail-icon { width: 16px; text-align: center; opacity: .85; font-size: 13px; }

/* ---------- blade ---------- */
.blade { min-width: 0; min-height: 0; display: flex; flex-direction: column; }
.blade-head {
  position: sticky; top: var(--topbar-height); z-index: 20;
  padding: 14px 24px 0; background: var(--bg); border-bottom: 1px solid var(--line);
}
.blade-head:has(.pivot) { padding-bottom: 0; }
.blade-head h1 { margin: 4px 0 10px; font-size: 20px; font-weight: 600; }
.crumbs { font-size: 12px; color: var(--text-faint); }
.crumbs a { color: var(--text-faint); text-decoration: none; }
.crumbs a:hover { color: var(--accent); text-decoration: underline; }
.crumb-sep { margin: 0 6px; opacity: .6; }
.commandbar { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; padding-bottom: 8px; min-height: 8px; }

/* ---------- pivot: the one row of tabs ----------
   Part of the frame, at the bottom edge of the blade head. Every page that has
   more than one view puts its tabs here and nowhere else, so moving between
   views never moves the tabs. */
.pivot { display: flex; gap: 2px; margin: 0 -24px; padding: 0 24px;
  border-top: 1px solid var(--line); }
.pivot-tab {
  padding: 9px 14px; margin-bottom: -1px;
  color: var(--text-soft); text-decoration: none; font-size: 13px;
  border-bottom: 2px solid transparent; white-space: nowrap;
}
.pivot-tab:hover { color: var(--text); background: var(--bg-hover); }
.pivot-tab.current { color: var(--text); border-bottom-color: var(--accent); }
.blade-body { padding: 20px 24px 32px; display: grid; gap: 16px; align-content: start; }
/* A surface whose content IS the page — a conversation, a canvas — asks for the
   blade to stop reserving space around it. */
.blade-body.fill { padding: 12px 16px 16px; display: flex; flex-direction: column;
  flex: 1 1 auto; min-height: 0; overflow: hidden; }
.blade-body.fill > * { flex: 1 1 auto; min-height: 0; }

/* ---------- controls ---------- */
button, .button {
  display: inline-flex; align-items: center; gap: 6px;
  background: transparent; color: var(--text); border: 1px solid transparent;
  border-radius: var(--radius); padding: 6px 10px; font: inherit; font-size: 13px;
  cursor: pointer; text-decoration: none;
}
.commandbar button, .commandbar .button { padding: 5px 9px; color: var(--text-soft); }
.commandbar button:hover:not(:disabled), .commandbar .button:hover { background: var(--bg-hover); color: var(--text); }
button:disabled { opacity: .45; cursor: default; }
button.primary, .button.primary {
  background: var(--accent-strong); border-color: var(--accent); color: #fff;
}
button.primary:hover:not(:disabled) { background: var(--accent); }
button.danger, .button.danger { color: var(--danger); }
button.danger:hover:not(:disabled) { background: var(--danger-bg); border-color: var(--danger-line); }
button.subtle { border-color: var(--line-strong); }
button.subtle:hover:not(:disabled) { background: var(--bg-hover); }

input, select, textarea {
  background: var(--bg-card); color: var(--text);
  border: 1px solid var(--line-strong); border-radius: var(--radius);
  padding: 7px 9px; font: inherit; font-size: 13px;
}
input:focus, select:focus, textarea:focus { outline: 2px solid var(--accent); outline-offset: -1px; }
label.field { display: grid; gap: 4px; font-size: 11px; text-transform: uppercase;
  letter-spacing: .07em; color: var(--text-faint); }
label.check { display: inline-flex; align-items: center; gap: 6px; font-size: 12px;
  color: var(--text-soft); white-space: nowrap; }
label.check input { width: auto; }

/* ---------- surfaces of content ---------- */
.card { background: var(--bg-card); border: 1px solid var(--line); border-radius: var(--radius-lg); padding: 16px; }
.cards { display: grid; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); gap: 12px; }
.filters { display: grid; grid-template-columns: repeat(auto-fill, minmax(190px, 1fr)); gap: 10px;
  background: var(--bg-card); border: 1px solid var(--line); border-radius: var(--radius-lg); padding: 14px; }
.filters .wide { grid-column: span 2; }
.bar { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }

/* ---------- toolbar ----------
   The row of controls above a result list. What goes where is structural, not
   per-page: searching and narrowing on the left, acting on the right. Wrapped,
   the two halves stay whole instead of interleaving. Never the `.filters` grid —
   that is for labelled fields, and it stretched checkboxes and buttons into
   190px cells wherever the grid happened to put them. */
.toolbar { display: flex; gap: 10px; align-items: flex-start; flex-wrap: wrap;
  justify-content: space-between; margin-bottom: 12px; }
.toolbar-main, .toolbar-actions { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
.toolbar-main { flex: 1 1 320px; min-width: 0; }
.toolbar-main > input[type=text], .toolbar-main > input:not([type]) { flex: 1 1 220px; min-width: 160px; }
.toolbar-actions { flex: 0 1 auto; justify-content: flex-end; }
/* A divider before the destructive end of the row. */
.toolbar-actions .sep { width: 1px; align-self: stretch; background: var(--line); margin: 2px 2px; }
.list { display: grid; gap: 6px; }
/* A grid item's default `min-width: auto` is the width of its longest unbroken
   run — an id, a token, a file path. The column then refuses to be narrower than
   that, the row pushes past the container, and the page itself becomes wider
   than the screen. Everything looks shifted, and it looks like a line-break
   problem because that is what it is: the text cannot break, so the layout does.
   `min-width: 0` lets the column shrink; the wrapping rules below let the text
   inside it break. */
.row { display: grid; grid-template-columns: auto 1fr; gap: 10px; align-items: start;
  background: var(--bg-card); border: 1px solid var(--line); border-radius: var(--radius); padding: 10px 12px; }
.row > * { min-width: 0; }
.row.picked { border-color: var(--accent); background: var(--accent-soft); }
.row .head { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; font-size: 11px; color: var(--text-soft); }
.row p { margin: 6px 0 0; font-size: 13px; color: var(--text); white-space: pre-wrap; overflow-wrap: anywhere; }

.empty { padding: 28px; border: 1px dashed var(--line-strong); border-radius: var(--radius-lg);
  color: var(--text-faint); text-align: center; }
.notice { padding: 10px 14px; border: 1px solid var(--warn); border-radius: var(--radius);
  background: #241c10; color: var(--warn); font-size: 12px; }
.error { color: var(--danger); font-size: 12px; }
.muted { color: var(--text-soft); font-size: 12px; }
.hint { color: var(--text-faint); font-size: 11px; }
.mono { font: 12px/1.5 ui-monospace, "Cascadia Mono", Consolas, monospace; overflow-wrap: anywhere; }

.tag { display: inline-block; font-size: 10px; border-radius: 99px; padding: 2px 8px;
  background: var(--accent-soft); color: var(--accent); }
.tag.personal { background: #2e2415; color: var(--warn); }
.tag.confidential { background: var(--danger-bg); color: var(--danger); }
.tag.assistant { background: #143028; color: var(--ok); }
.tag.neutral { background: var(--bg-hover); color: var(--text-faint); }
.pill { display: inline-block; font-size: 10px; color: var(--text-soft);
  background: var(--bg-hover); border-radius: 99px; padding: 2px 8px; }

/* ---------- dialog ---------- */
dialog.panel { border: 0; padding: 0; background: transparent; color: var(--text);
  width: min(780px, calc(100vw - 24px)); }
dialog.panel::backdrop { background: #05070ccc; backdrop-filter: blur(3px); }
.panel-box { background: var(--bg-raised); border: 1px solid var(--line-strong);
  border-radius: var(--radius-lg); overflow: hidden; }
.panel-head, .panel-bar, .panel-foot {
  display: flex; align-items: center; gap: 8px; padding: 10px 14px; border-bottom: 1px solid var(--line); }
.panel-head h2 { margin: 0; flex: 1; font-size: 15px; }
.panel-bar { flex-wrap: wrap; }
.panel-foot { border: 0; border-top: 1px solid var(--line); justify-content: flex-end; }
.panel textarea { display: block; width: 100%; min-height: 340px; border: 0; border-radius: 0;
  resize: vertical; font: 13px/1.55 ui-monospace, "Cascadia Mono", Consolas, monospace; tab-size: 2; }

@media (max-width: 860px) {
  /* ONE column, not a zero-width one beside it.
     The rail is taken out of the flow here — `position: fixed`, and `display:
     none` until it is opened — so it occupies no grid cell at all. With two
     columns declared, automatic placement then put the blade in the FIRST one,
     which is `0` wide: every page's content spilled out of a zero-width column
     and stacked, on every surface, at every width below 860px. It read as "the
     page is almost empty", and no amount of work inside the blade could fix it
     because the blade itself had no width to work with. */
  .portal { grid-template-columns: 1fr; }
  .rail { position: fixed; z-index: 30; width: var(--rail-width); display: none; }
  .portal.open .rail { display: block; }
  .blade-body, .blade-head { padding-left: 14px; padding-right: 14px; }
  .filters .wide { grid-column: span 1; }
}


/* ==========================================================================
   Phones.
   Everything below this line applies only at 640px and under; the desktop
   layout above it is untouched by design. 640px rather than the frame's
   existing 860px, because those are two different questions: at 860 the rail
   stops fitting beside the content and becomes a drawer, which is as true of a
   tablet as of a phone. At 640 the assumptions change — one thumb, no hover, a
   soft keyboard that eats half the screen, and a browser that zooms the page
   whenever a field smaller than 16px takes focus.
   ========================================================================== */
@media (max-width: 640px) {
  /* ---- top bar ---- */
  .topbar { padding: 0 8px; gap: 8px; }
  .brand { font-size: 14px; }
  /* The name goes; the avatar stays. Who is signed in is still answered, in the
     space a phone actually has. */
  .account-name { display: none; }
  .signout { font-size: 12px; }

  /* ---- rail ---- */
  /* Wide enough to read a label, narrow enough to show that the page is still
     behind it and a tap outside will bring it back. */
  .rail { width: min(78vw, 300px); box-shadow: 0 0 60px rgba(0,0,0,.55); }
  .rail-scrim {
    position: fixed; inset: var(--topbar-height) 0 0 0;
    z-index: 29; background: rgba(0,0,0,.5);
  }
  .portal.open .rail-scrim { display: block; }

  /* ---- a full-height surface stops filling ---- */
  /* Its parts sat side by side because there was room; stacked, they are taller
     than the screen. Kept at the viewport height with `overflow: hidden`, the
     second half is simply cut off — which is what an empty main area was. The
     page scrolls instead. `fill-always` opts out: a conversation has to keep its
     input row at the bottom edge, so it stays exactly one screen tall — measured
     in `dvh`, because `vh` on a phone is the height with the browser's own bars
     hidden and puts the input under them. */
  .portal.fill:not(.fill-always) { height: auto; min-height: calc(100dvh - var(--topbar-height)); }
  .blade-body.fill:not(.fill-always) { display: block; overflow: visible; flex: 0 0 auto; }
  .blade-body.fill:not(.fill-always) > * { flex: none; min-height: 0; }
  .portal.fill-always { height: calc(100dvh - var(--topbar-height)); }

  /* ---- blade ---- */
  .blade-head { padding: 10px 14px 0; }
  .blade-head h1 { font-size: 17px; margin: 2px 0 8px; }
  /* The breadcrumb repeats what the rail and the pivot already say, and it is
     the first thing worth the space it costs. */
  .crumbs { display: none; }
  .blade-body { padding: 14px 14px 24px; }

  /* A command bar wraps; six tabs do not. The pivot scrolls sideways instead of
     stacking into three rows that push the content off the screen — and it keeps
     its place at the bottom edge of the head, which is the whole point of it. */
  .commandbar { gap: 8px; }
  .commandbar select, .commandbar input { flex: 1 1 140px; min-width: 0; }
  .pivot { margin: 0 -14px; padding: 0 14px; overflow-x: auto; scrollbar-width: none; }
  .pivot::-webkit-scrollbar { display: none; }
  .pivot-tab { padding: 10px 12px; }

  /* ---- controls ---- */
  /* 16px is not a preference: below it, mobile Safari zooms the page when a
     field takes focus and never zooms back. */
  input, select, textarea { font-size: 16px; }
  button, .button { min-height: 38px; }
  .commandbar button, .commandbar .button { min-height: 34px; }

  /* ---- toolbar ---- */
  /* The two halves stack instead of interleaving, and each fills the width, so
     the order stays the one the desktop has: narrow the list, then act on it. */
  .toolbar { flex-direction: column; align-items: stretch; gap: 8px; }
  .toolbar-main, .toolbar-actions { width: 100%; }
  .toolbar-actions { justify-content: flex-start; }
  .toolbar-actions .sep { display: none; }
  .toolbar-main > input[type=text], .toolbar-main > input:not([type]) { flex: 1 1 100%; }

  /* ---- content ---- */
  .filters { grid-template-columns: 1fr; padding: 12px; }
  .filters .wide { grid-column: span 1; }
  .cards { grid-template-columns: 1fr; }
  .card { padding: 12px; }
  .row { padding: 8px 10px; }

  /* A table cannot reflow without losing the alignment that makes it a table, so
     it scrolls inside its own box rather than widening the page. */
  /* Wrapping beats alignment on a phone: a cell that breaks is readable, a row
     that refuses to break makes the page wider than the screen and takes every
     other element with it. The scroll box stays as the fallback for a table that
     genuinely cannot narrow. */
  table { display: block; overflow-x: auto; }
  td, th { overflow-wrap: anywhere; }

  /* A dialog on a phone is the screen. */
  dialog.panel { width: 100vw; max-width: 100vw; height: 100dvh; margin: 0; }
  .panel-box { height: 100dvh; border-radius: 0; display: flex; flex-direction: column; }
  .panel textarea { flex: 1 1 auto; min-height: 0; }
}
