/* pipe — the SHELL, one sheet for every page.
 *
 * The side panel, the phone tab bar, the wrap grid that seats them, and
 * the palette they and everything else draw from. Every page loads this
 * BEFORE its one content sheet (site.css, mkt.css or docs.css — xtask's
 * head_for emits the pair), so the shell exists exactly once: the three
 * per-sheet copies it replaces had already drifted (a round dot on the
 * docs brand, a floating card panel on the app) and were the drift
 * generator Sam called gravely overcomplicated. A content sheet may
 * extend the shell (the app's wrap seats two panes; the marketing home
 * locks its height) but never restates it.
 *
 * The palette is pipe.local's settled scheme (the box dashboard mirrors
 * this block verbatim): neutral greys, one robin's-egg blue spent super
 * light as fill and deep as text, both polarities, the OS choosing. Two
 * naming families point at one set of values — site.css and mkt.css grew
 * up on basho's names (--fg/--dim/--panel/--fill), docs.css on the
 * dashboard's (--ink/--muted/--card/--bg2) — so both resolve here and a
 * retune stays a one-block edit. New rules prefer the basho names.
 */

/* ── the palette, both polarities ────────────────────────────────────── */
:root {
  --bg: #f4f4f5;
  --fg: #1a1a1c;
  --dim: #64666a;
  /* one step below --dim, still 4.5:1 on every surface — the app sets
     live text in it (tab labels), so the gate holds it, not taste */
  --faint: #67696d;
  --line: #dfe0e2;
  --panel: #ffffff;
  --fill: #ebebed;
  --accent: #1c608f;
  --accent-soft: #e9f4fb;
  --danger: #b23315;
  /* the dashboard's aliases: same values, docs.css's names */
  --ink: #1a1a1c;
  --muted: #64666a;
  --card: #ffffff;
  --bg2: #ebebed;
  --warn: #96690a;
  --bad: #a83c2e;
  --ok: #2c7d5b;
  /* the two faces, once */
  --sans: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  --mono: ui-monospace, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace;
  /* elevation, one voice */
  --shadow: 0 1px 2px rgba(10,10,12,.05), 0 8px 24px rgba(10,10,12,.05);
  /* the terminal quote: one polarity in both themes — a quote, not a surface */
  --term-bg: #18191b;
  --term-ink: #e8eaeb;
  --term-dim: #9a9da1;
  --term-accent: #a5d5ef;
  color-scheme: light dark;
}
@media (prefers-color-scheme: dark) {
  :root {
    --bg: #141416;
    --fg: #e9e9eb;
    --dim: #a2a4a8;
    --faint: #8e9096;
    --line: #2e2e33;
    --panel: #1f1f23;
    --fill: #1a1a1d;
    --accent: #a5d5ef;
    --accent-soft: #1f2b34;
    --danger: #e0806a;
    --ink: #e9e9eb;
    --muted: #a2a4a8;
    --card: #1f1f23;
    --bg2: #1a1a1d;
    --warn: #d9a53f;
    --bad: #e0806a;
    --ok: #6bbb8c;
    --term-bg: #1c1e21;
    --shadow: 0 1px 2px rgba(0,0,0,.3), 0 10px 30px rgba(0,0,0,.32);
  }
}

/* ── base, shared ────────────────────────────────────────────────────── */
* { box-sizing: border-box; }
/* no scrollbars anywhere — operator's call; scrolling itself is untouched */
* { scrollbar-width: none; }
*::-webkit-scrollbar { display: none; }
/* `hidden` always wins: auth keeps signed-in-only sections in the DOM and
   toggles them by attribute — a stray display rule must not leak them */
[hidden] { display: none !important; }
html { -webkit-text-size-adjust: 100%; }
html, body {
  margin: 0;
  background-color: var(--bg);
  /* the faint glow from above the top edge, one spelling for every page */
  background-image: radial-gradient(1100px 500px at 50% -120px, color-mix(in srgb, var(--accent) 6%, transparent), transparent 70%);
  background-attachment: fixed;
  color: var(--fg);
}
body {
  font: 15px/1.6 var(--sans);
  -webkit-font-smoothing: antialiased;
}
:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 3px; }

/* the terminal quote — dark in both polarities, everywhere it appears */
pre.term {
  background: var(--term-bg);
  color: var(--term-ink);
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: 11px 14px;
  margin: 10px 0 18px;
  font: 12.5px/1.6 var(--mono);
  white-space: pre-wrap;
  overflow-x: auto;
}
pre.term .p { color: var(--term-accent); }
pre.term .c { color: var(--term-dim); }
pre.term.install { display: flex; align-items: center; gap: 0.6ch; cursor: pointer; white-space: nowrap; }
pre.term.install .copy { margin-left: auto; color: var(--term-dim); font-size: 11px; padding: 4px 8px; user-select: none; flex: none; text-transform: uppercase; letter-spacing: 0.06em; }
pre.term.install:hover .copy { color: var(--term-ink); }

/* ── shared components ───────────────────────────────────────────────── */
/* The button, one base for every sheet's spelling — .btn is the app's,
   .button the marketing pages' — with the variants (.mini, .plain,
   .danger, .provider, the tier CTAs) staying where their pages live. */
.btn, .button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 8px 16px;
  max-width: 100%;
  border: 0;
  border-radius: 8px;
  cursor: pointer;
  font: inherit;
  font-weight: 600;
  text-align: center;
  text-decoration: none;
  color: var(--bg);
  background: var(--accent);
  transition: transform 0.12s ease, filter 0.12s ease, color 0.12s ease, border-color 0.12s ease;
}
:is(.btn, .button):hover:not(:disabled) { filter: brightness(1.08); transform: translateY(-1.5px); }
:is(.btn, .button):active:not(:disabled) { transform: translateY(0) scale(0.985); }
:is(.btn, .button):disabled { opacity: 0.5; cursor: default; }

/* The card: the dashboard's surface — white on the grey ground, hairline
   edge, soft shadow, 12px corners. pipe.local is built from these; so is
   every page here now. */
.card {
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 12px;
  box-shadow: var(--shadow);
}

/* The input slot: one field look for every sheet's spelling — the app's
   .well, the marketing composer's bare input, a select anywhere. The
   widget types that draw themselves stay out. */
.well,
input:not([type="checkbox"], [type="radio"], [type="color"], [type="range"], [type="file"]),
textarea,
select {
  font: inherit;
  color: var(--fg);
  background: var(--fill);
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: 8px 11px;
  transition: border-color 0.12s ease, box-shadow 0.2s ease;
}
:is(.well, input, textarea, select):focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 15%, transparent);
}

/* the quiet second line under a heading */
.sub {
  color: var(--dim);
  font-size: 13px;
  line-height: 1.6;
  margin: 0 0 18px;
  max-width: 68ch;
}

/* the inline code chip */
code {
  font-family: var(--mono);
  font-size: 0.87em;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 4px;
  padding: 1px 5px;
}
pre code { background: none; border: 0; padding: 0; font-size: inherit; }

/* The key–value table: command (or term) left in accent mono, its meaning
   right, a hairline between rows — the dashboard's idiom, everywhere a
   page states facts two columns at a time. Stacks below 560px. */
table.q {
  border-collapse: collapse;
  width: 100%;
  font-size: 13px;
  margin: 6px 0 24px;
}
table.q td {
  padding: 10px 18px 10px 0;
  vertical-align: top;
  line-height: 1.55;
  border-bottom: 1px solid var(--line);
}
table.q tr:last-child td { border-bottom: 0; }
table.q td:first-child, table.q td.cmd {
  font-family: var(--mono);
  font-size: 12.5px;
  font-weight: 600;
  color: var(--accent);
  white-space: nowrap;
}
table.q td.desc, table.q td.yes { color: var(--dim); }
@media (max-width: 560px) {
  table.q, table.q tbody, table.q tr { display: block; width: 100%; }
  table.q td { display: block; width: 100%; white-space: normal; border-bottom: 0; }
  table.q td:first-child, table.q td.cmd { padding-bottom: 1px; }
  table.q td.desc { padding: 0 0 12px; border-bottom: 1px solid var(--line); margin-bottom: 10px; }
}

/* ── the wrap: panel left, page right ────────────────────────────────── */
/* Capped growth but LEFT-ANCHORED: the panel hugs the viewport's edge at
   every width and the dead space lives on the right, as on pipe.local.
   minmax(0,·), NOT bare 1fr — 1fr means minmax(auto, 1fr), and one wide
   child (the footer crawl) would push the whole page off-screen. */
.wrap {
  min-height: 100vh;
  min-height: 100dvh;
  display: grid;
  grid-template-columns: 232px minmax(0, 1fr);
  grid-template-rows: minmax(0, 1fr) auto;
}
.wrap > .nav, .wrap > nav[data-nav] { grid-column: 1; grid-row: 1 / -1; }
.wrap > main { grid-column: 2; grid-row: 1; }
.wrap > footer { grid-column: 2; grid-row: 2; }

/* ── the side panel (pipe.local's sidenav, the one copy) ─────────────── */
.nav, nav[data-nav] {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 18px 12px 14px;
  background: var(--fill);
  border-right: 1px solid var(--line);
  position: sticky;
  top: 0;
  height: 100vh;
  height: 100dvh;
  overflow-y: auto;
  color: var(--dim);
  /* The panel's type is pinned HERE, not inherited: the content sheets set
     different body line-heights (1.55 / 1.6), and an inherited metric made
     the rows a fraction taller on one page than the next — the panel
     visibly bounced crossing into the docs. */
  font: 500 14px/1.5 var(--sans);
  z-index: 10;
}
:is(.nav, nav[data-nav]) :is(a, b) {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 10px;
  border: 0;
  border-radius: 9px;
  font-weight: 500;
  white-space: nowrap;
  text-decoration: none;
  color: var(--dim);
}
:is(.nav, nav[data-nav]) a:hover { background: var(--panel); color: var(--fg); }
:is(.nav, nav[data-nav]) b { background: var(--accent-soft); color: var(--accent); font-weight: 600; }
:is(.nav, nav[data-nav]) .ic { width: 17px; height: 17px; flex: none; opacity: 0.85; }
:is(.nav, nav[data-nav]) .ic svg,
.tabbar .glyph svg {
  width: 100%;
  height: 100%;
  display: block;
  stroke: currentColor;
  fill: none;
  stroke-width: 1.7;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* the brand: the mark — the | — and the word. One shape everywhere. */
:is(.nav, nav[data-nav]) .brand {
  font-weight: 700;
  font-size: 16px;
  color: var(--fg);
  background: none;
  margin-bottom: 12px;
}
:is(.nav, nav[data-nav]) .mark {
  width: 4px;
  height: 16px;
  border-radius: 2px;
  background: var(--accent);
  display: inline-block;
  box-shadow: 0 0 0 0 color-mix(in srgb, var(--accent) 0%, transparent);
  transition: box-shadow 0.2s ease, transform 0.2s ease;
}
:is(.nav, nav[data-nav]) .brand:hover .mark {
  box-shadow: 0 0 14px 1px color-mix(in srgb, var(--accent) 45%, transparent);
  transform: rotate(12deg) scaleY(1.1);
}

/* the member cluster and the tag, pinned to the panel's foot */
:is(.nav, nav[data-nav]) .flux {
  margin-top: auto;
  display: inline-flex;
  align-items: center;
  gap: 5px;
  color: var(--dim);
  font-size: 12px;
  padding: 8px 10px 2px;
}
:is(.nav, nav[data-nav]) .flux .drop {
  width: 7px;
  height: 9px;
  border-radius: 50% 50% 50% 50% / 40% 40% 60% 60%;
  background: var(--accent);
  display: inline-block;
}
:is(.nav, nav[data-nav]) .flux b { color: var(--fg); font-size: 12px; background: none; padding: 0; }
:is(.nav, nav[data-nav]) :is(.signout, .alpha) { font-size: 12px; }
:is(.nav, nav[data-nav]) .alpha {
  color: var(--dim);
  border: 1px solid var(--line);
  border-radius: 999px;
  padding: 1px 8px;
  align-self: flex-start;
  margin: 6px 10px 0;
}
/* a signed-out panel has no flux row; the tag alone takes the foot */
:is(.nav, nav[data-nav]) > .alpha:first-of-type { margin-top: auto; }

/* ── the tab bar (phone; chrome.ts builds it for everyone) ───────────── */
.tabbar { display: none; }

/* ── the handoff: one width, every sheet ─────────────────────────────── */
@media (max-width: 760px) {
  .wrap { grid-template-columns: minmax(0, 1fr); }
  .wrap > main { grid-column: 1; }
  .wrap > footer { grid-column: 1; }
  .nav, nav[data-nav] { display: none; }
  .tabbar {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 10;
    display: flex;
    background: var(--fill);
    border-top: 1px solid var(--line);
    padding: 6px 4px max(6px, env(safe-area-inset-bottom));
  }
  .tabbar a, .tabbar b {
    flex: 1;
    min-height: 44px;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 3px;
    /* longhands, not the font shorthand: the selection guard compares the
       shared rule's font-weight against the selected cell's, and a
       shorthand hides the property from it */
    font-family: var(--sans);
    font-size: 11px;
    line-height: 1.4;
    font-weight: 400;
    letter-spacing: 0.04em;
    color: var(--dim);
    border: 0;
    text-decoration: none;
    position: relative;
  }
  /* selection carries weight as well as colour (#790 criterion 9) */
  .tabbar b { color: var(--accent); font-weight: 600; }
  .tabbar .glyph { width: 20px; height: 20px; }
  .tabbar .count {
    position: absolute;
    top: 2px;
    right: 50%;
    margin-right: -22px;
    font-size: 11px;
    color: var(--accent);
  }
  /* content clears the bar instead of hiding under it; the app's
     height-locked wrap spends its own clearance in site.css */
  body.has-tabbar main { padding-bottom: calc(78px + env(safe-area-inset-bottom)); }
}
