/*
  Copyright 2026 Carlos Eduardo Arango Gutierrez
  SPDX-License-Identifier: Apache-2.0

  The shared stylesheet for the coffee-bar site. Extracted from the inline
  <style> block of site/index.html and recoloured per the 2026-08-04 design,
  section 3.2. This was a move plus a recolour, not a rewrite.

  TWO COLOURS, TWO JOBS. Never mix them.

    --state   the liquid in the icon, held segments on the timeline, the
              .eyebrow square, list bullets. It means "held awake".
    --action  button backgrounds, link underlines and hover, :focus-visible
              outlines, the sidebar's current-page marker. It means
              "you can operate this".

  The old --liquid token is now --state. The name changed because the colour
  now means "held", and a second colour now means "interactive".

  NEITHER COLOUR CARRIES BODY TEXT. That is a DESIGN RULE, not a measurement.
  Only one of the four combinations actually fails 4.5:1:

      --action #FF9500 on light #F2F0EB   1.93   fails
      --action #FF9F0A on dark  #101013   9.24   passes
      --state  #A2571E on light #F2F0EB   4.71   passes
      --state  #B8682A on dark  #101013   4.57   passes

  Holding both out of body text in both appearances keeps this one rule
  instead of four exceptions. A filled button is the safe inverse: ink on
  --action measures 8.51 in light and 9.10 in dark.

  Sidebar markup contract — plain links, no JavaScript:

    <div class="shell">
      <nav class="sidebar" aria-label="Site">
        <a class="sidebar-mark" href="index.html">coffee-bar</a>
        <ul>
          <li><a href="index.html" aria-current="page">Home</a></li>
          <li><a href="install.html">Install</a></li>
          <li><a href="docs.html">Docs</a></li>
          <li><a href="changelog.html">Changelog</a></li>
        </ul>
        <p class="sidebar-version"><a href="changelog.html">v0.1.1</a></p>
      </nav>
      <div class="wrap"><!-- page content --></div>
    </div>

  .wrap still renders correctly on its own, so a page that carries no sidebar
  is unaffected.
*/

:root {
  color-scheme: light dark;
  --state:  #A2571E;  /* the liquid; held awake */
  --action: #FF9500;  /* Apple systemOrange; buttons, links, focus */
  --rest:   #6B7683;  /* released; free to sleep */
  --ink:    #121214;
  --paper:  #F2F0EB;
  --fg:     var(--ink);
  --bg:     var(--paper);
  --dim:    #55585F;
  --line:   #E0DDD5;
  --panel:  #E9E6DE;
}
@media (prefers-color-scheme: dark) {
  :root {
    --state:  #B8682A;
    --action: #FF9F0A;
    --fg:     #F2F1EE;
    --bg:     #101013;
    --dim:    #9AA0A8;
    --line:   #24242A;
    --panel:  #191920;
  }
}

*, *::before, *::after { box-sizing: border-box; }

body {
  margin: 0; background: var(--bg); color: var(--fg);
  font: 16.5px/1.7 -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, sans-serif;
  -webkit-font-smoothing: antialiased;
}
.wrap { max-width: 46rem; margin: 0 auto; padding: 4rem 1.5rem 6rem; }

.mono, h1, .eyebrow, code, pre, .track-label, .phase, .state-name {
  font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, monospace;
}

/* ── Focus: visible on every interactive element ───────────────────────── */
:focus-visible {
  outline: 2px solid var(--action); outline-offset: 3px; border-radius: 2px;
}

/* ── Shell: sidebar plus content ───────────────────────────────────────── */
/* Below 48rem the sidebar is a horizontal row above the content. This is the
   default, so a narrow viewport needs no query. */
.shell { max-width: 64rem; margin: 0 auto; }
.shell > .wrap { margin: 0; max-width: 46rem; }

.sidebar { padding: 2rem 1.5rem 0; }
.sidebar-mark {
  display: inline-flex; align-items: center; min-height: 44px;
  font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, monospace;
  font-weight: 700; letter-spacing: -.03em; text-decoration: none;
  color: var(--fg);
}
.sidebar ul {
  list-style: none; margin: 0; padding: 0;
  display: flex; flex-wrap: wrap; gap: .15rem .35rem;
}
/* Scoped to the nav list, so neither .sidebar-mark nor .sidebar-version picks
   up the 44px page-link treatment. */
.sidebar ul a {
  display: flex; align-items: center; min-height: 44px; padding: 0 .75rem;
  border-radius: 6px; text-decoration: none; color: var(--dim);
  font-size: .9rem;
}
.sidebar ul a:hover { color: var(--fg); background: var(--panel); }
.sidebar a[aria-current="page"] {
  color: var(--fg); font-weight: 650;
  box-shadow: inset 0 -2px 0 var(--action);
}

/* The version badge, last child of nav.sidebar. The version string lives in
   the HTML and never here. It stays in normal flow, so it rides the sticky
   sidebar at >=48rem instead of fighting it. */
.sidebar-version {
  margin: .9rem 0 0; padding: 0 .75rem;
  font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, monospace;
  font-size: .78rem; line-height: 1.5;
}
.sidebar-version a { color: var(--dim); text-decoration: none; }
.sidebar-version a:hover,
.sidebar-version a:focus-visible {
  color: var(--fg);
  text-decoration: underline; text-decoration-color: var(--action);
  text-decoration-thickness: 2px; text-underline-offset: 3px;
}

@media (min-width: 48rem) {
  .shell {
    display: grid; grid-template-columns: 13rem minmax(0, 1fr);
    gap: 3rem; align-items: start; padding: 0 1.5rem;
  }
  .shell > .wrap { padding-left: 0; padding-right: 0; }
  .sidebar { padding: 4rem 0 0; position: sticky; top: 2rem; }
  .sidebar ul { display: block; margin-top: 1.5rem; }
  .sidebar li + li { margin-top: .1rem; }
  .sidebar a[aria-current="page"] {
    background: var(--panel);
    box-shadow: inset 2px 0 0 var(--action);
  }
}

/* ── Hero ──────────────────────────────────────────────────────────────── */
.hero { display: flex; align-items: center; gap: 1.25rem; margin-bottom: 1.1rem; }
.appicon {
  width: 84px; height: 84px; flex: none; border-radius: 19%;
  display: block; box-shadow: 0 1px 3px rgba(0,0,0,.18);
}
h1 {
  font-size: clamp(2rem, 7vw, 3rem); font-weight: 700;
  letter-spacing: -0.045em; line-height: 1; margin: 0;
}
.tag {
  font-size: clamp(1.05rem, 2.6vw, 1.28rem); line-height: 1.45;
  margin: 0 0 3rem; max-width: 34ch; text-wrap: balance;
}
.tag em { font-style: normal; border-bottom: 2px solid var(--fg); }
/* On the hero, .hero's own margin supplies the gap under the wordmark. A page
   that puts the tagline straight after a bare <h1> had no gap at all —
   measured 0.0px at 375, 768 and 1200. This only fires on that second shape,
   so the hero is untouched. */
h1 + .tag { margin-top: .6rem; }

.eyebrow {
  display: flex; align-items: center; gap: .6rem;
  font-size: .72rem; font-weight: 600; text-transform: uppercase;
  letter-spacing: .16em; color: var(--dim); margin: 3.5rem 0 1rem;
}
.eyebrow::before {
  content: ""; width: .5rem; height: .5rem; flex: none; background: var(--state);
}
h2 { margin: 0; font-size: 1rem; }
p { margin: 0 0 1.1rem; }
/* Links carry body-text colour. The action colour rides the underline only,
   because it does not reach 4.5:1 as a foreground. */
a {
  color: inherit; text-underline-offset: 3px;
  text-decoration-color: var(--action); text-decoration-thickness: 1.5px;
}
a:hover { text-decoration-thickness: 2.5px; }
a:focus-visible { outline: 2px solid var(--action); outline-offset: 3px; border-radius: 2px; }
strong { font-weight: 650; }

/* ── The download button ───────────────────────────────────────────────── */
/* 44px is Apple's minimum hit target and is required. */
.btn-download {
  display: inline-flex; align-items: center; justify-content: center;
  min-height: 44px; padding: 0 1.15rem;
  background: var(--action); color: var(--ink);
  border-radius: 8px; font-weight: 650; text-decoration: none;
}
.btn-download:hover { filter: brightness(1.06); }

/* The facts line under the button. Secondary information under a primary
   action: it sits tight to the button and must not compete with it. --dim on
   --bg measures 6.26 light and 7.26 dark, so it stays legible at this size. */
.dl-meta {
  /* Tight to the button above, but keep the normal paragraph gap below: a
     zero bottom margin collided with the next paragraph at every width. */
  margin: .55rem 0 1.1rem;
  font-size: .84rem; line-height: 1.5; color: var(--dim);
}

/* ── Signature: the assertion timeline ─────────────────────────────────── */
.figure {
  background: var(--panel); border: 1px solid var(--line);
  border-radius: 10px; padding: 1.4rem 1.35rem 1.15rem; margin: 0 0 1.25rem;
}
.row { display: grid; grid-template-columns: 6.5rem 1fr; align-items: center; gap: .9rem; }
.row + .row { margin-top: .55rem; }
.track-label { font-size: .74rem; color: var(--dim); text-align: right; white-space: nowrap; }
.track { display: flex; gap: 3px; height: 1.05rem; }
.seg { border-radius: 2px; }
.seg.work { background: var(--state); }
.seg.wait { background: var(--rest); opacity: .38; }
/* caffeinate holds CONTINUOUSLY. One unbroken bar, because segmenting it
   would imply it ever lets go. */
.track.caffeinate .seg { background: var(--state); opacity: .45; }

.axis { display: grid; grid-template-columns: 6.5rem 1fr; gap: .9rem; margin-top: .45rem; }
.phases { display: flex; gap: 3px; }
.phase {
  font-size: .62rem; letter-spacing: .02em; color: var(--dim);
  padding: .3rem 0 0 .4rem; border-left: 1px solid var(--line);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.caption { font-size: .82rem; color: var(--dim); margin: 0 0 2rem; }
.caption b { color: var(--fg); font-weight: 600; }

@media (prefers-reduced-motion: no-preference) {
  .track.coffeebar .seg.wait {
    background: var(--state); opacity: .45;
    animation: release .5s ease-out forwards;
  }
  .track.coffeebar .seg.wait.w1 { animation-delay: .75s; }
  .track.coffeebar .seg.wait.w2 { animation-delay: 1.15s; }
}
@keyframes release { to { background: var(--rest); opacity: .38; } }

/* ── The menu-bar states, in the real artwork ──────────────────────────── */
.states { display: flex; flex-wrap: wrap; gap: 1.6rem; margin: 0 0 1rem; }
.state { display: flex; align-items: flex-start; gap: .7rem; min-width: 13rem; flex: 1; }
.state svg { width: 26px; height: 26px; flex: none; color: var(--fg); margin-top: .1rem; }
.state-name { display: block; font-size: .78rem; font-weight: 600; letter-spacing: -.01em; }
.state-what { display: block; font-size: .84rem; color: var(--dim); line-height: 1.5; }

/* ── Lists ─────────────────────────────────────────────────────────────── */
ul.does { list-style: none; padding: 0; margin: 0; }
ul.does li { position: relative; padding-left: 1.5rem; margin: 0 0 .8rem; }
ul.does li::before {
  content: ""; position: absolute; left: 0; top: .62em;
  width: .45rem; height: .45rem; background: var(--state); border-radius: 1px;
}
.note {
  border-left: 2px solid var(--state); padding: .15rem 0 .15rem 1.1rem;
  color: var(--dim); margin: 1.75rem 0 0;
}

/* ── Tables ────────────────────────────────────────────────────────────── */
/* Three consumers: the changelog's release facts, the Docs comparisons, and
   the policy bench's static 24-row decision table. That last one is the
   no-JavaScript and crawler path, so it is load-bearing, not decorative. It
   has to stay readable at 24 rows.

   Rules use --line. Banding uses --panel. NEVER --state or --action: --state
   means "held awake" on this site, and a striped row means nothing of the
   kind.

   Wrap a wide table in <div class="table-wrap"> so the overflow lives on the
   table's own container. Never let a table scroll the page. */
.table-wrap { overflow-x: auto; margin: 0 0 1.5rem; }
table {
  border-collapse: collapse;
  width: 100%; max-width: 100%;
  font-size: .88rem; line-height: 1.5;
  margin: 0 0 1.5rem;
}
.table-wrap > table { margin: 0; }
caption {
  caption-side: top; text-align: left;
  font-size: .82rem; color: var(--dim); padding: 0 0 .5rem;
}
th, td {
  text-align: left; vertical-align: top;
  padding: .45rem .7rem;
  border-bottom: 1px solid var(--line);
}
/* The header row must be told apart at a glance from 24 body rows. */
thead th {
  font-size: .72rem; text-transform: uppercase; letter-spacing: .08em;
  font-weight: 600; color: var(--dim);
  border-bottom: 2px solid var(--line);
}
tbody tr:nth-child(even) { background: var(--panel); }
tbody tr:last-child > * { border-bottom: 0; }
/* A row-label column, as the release facts use. Short strings, so keeping
   them on one line costs nothing. */
tbody th { font-weight: 650; white-space: nowrap; }
/* The hard case: a 64-character SHA-256. It wraps inside its own cell rather
   than pushing the table wider than the column it sits in. */
td code, td .mono { overflow-wrap: anywhere; word-break: break-word; }

/* ── Install: a real sequence, so the numbering carries meaning ────────── */
ol.steps { list-style: none; counter-reset: s; padding: 0; margin: 0; }
ol.steps > li { counter-increment: s; position: relative; padding-left: 2.4rem; margin-bottom: 1.8rem; }
ol.steps > li::before {
  content: counter(s, decimal-leading-zero);
  position: absolute; left: 0; top: .15em;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: .78rem; color: var(--dim); font-weight: 600;
}
ol.steps p { margin: .35rem 0 .6rem; }
pre {
  background: var(--panel); border: 1px solid var(--line);
  padding: .8rem .95rem; border-radius: 6px; overflow-x: auto;
  font-size: .82rem; margin: 0; line-height: 1.5;
}
pre.hooks { max-height: 22rem; overflow-y: auto; }
code { font-size: .875em; }
p code, li code { background: var(--panel); padding: .1em .35em; border-radius: 3px; }

footer {
  margin-top: 4.5rem; padding-top: 1.5rem; border-top: 1px solid var(--line);
  color: var(--dim); font-size: .85rem;
}
/* The trademark line. The quietest text on the page, and it must stay that
   way: it is legal boilerplate, not something to read first. It still has to
   be readable, so it holds --dim (6.26 light, 7.26 dark) and stops at
   .75rem rather than shrinking further. */
.tm {
  margin: .9rem 0 0;
  font-size: .75rem; line-height: 1.5; color: var(--dim);
  max-width: 62ch;
}

/* ── The policy bench, on Home ─────────────────────────────────────────── */
/* The controls carry `hidden` in the markup and assets/bench.js removes it,
   only after a full render has succeeded. The two [hidden] rules below are
   load-bearing: the `display` declarations override the attribute's UA rule,
   so without them a visitor with JavaScript off sees dead controls. */
.bench-controls {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr));
  gap: .9rem 1.5rem; margin: 0 0 1.25rem;
  background: var(--panel); border: 1px solid var(--line);
  border-radius: 10px; padding: 1.1rem 1.25rem 1.25rem;
}
.bench-controls[hidden] { display: none; }
.bench-controls fieldset { border: 0; margin: 0; padding: 0; min-width: 0; }
.bench-controls legend {
  padding: 0 0 .25rem; font-size: .7rem; font-weight: 600;
  text-transform: uppercase; letter-spacing: .14em; color: var(--dim);
  font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, monospace;
}
/* 44px is Apple's minimum hit target and is required. */
.bench-opt {
  display: flex; align-items: center; gap: .6rem;
  min-height: 44px; cursor: pointer; font-size: .92rem;
}
.bench-opt input { flex: none; width: 1.05rem; height: 1.05rem; accent-color: var(--action); }
.bench-range { display: flex; align-items: center; gap: .7rem; min-height: 44px; }
.bench-range[hidden] { display: none; }
.bench-range input[type="range"] { flex: 1 1 6rem; min-width: 5rem; accent-color: var(--action); }
.bench-range output {
  flex: none; min-width: 3.4rem; text-align: right; font-size: .82rem;
  font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, monospace;
}

/* The segment the Sessions control points at. An outline, not a hue, so it
   does not compete with the two brand colours. */
.seg.now { outline: 2px solid var(--fg); outline-offset: 2px; }

/* NOTE: the decision table itself needs NOTHING here. It uses the shared
   `.table-wrap`, `table`, `caption`, `thead th` and banding rules that
   site.css already ships — including the comment about telling a header row
   apart from 24 body rows, which was written for exactly this table. */

/* The second lock on reduced motion. bench.js sets this attribute from
   matchMedia, so a segment cannot animate even if the media query above the
   `release` keyframes is ever edited away.
   The selector carries .coffeebar and .wait so it outranks
   `.track.coffeebar .seg.wait`, which is the only rule that sets an
   animation. Without them this lock is inert — measured, see the task-1
   report. */
.track[data-motion="reduce"] .seg,
.track.coffeebar[data-motion="reduce"] .seg.wait { animation: none; }

.bench-readout {
  border: 1px solid var(--line); border-radius: 10px;
  padding: 1rem 1.15rem; margin: 0 0 1.1rem;
}
.bench-readout p { margin: 0; font-size: .92rem; }
.bench-readout p + p { margin-top: .5rem; }
.bench-holds { list-style: none; margin: .6rem 0 0; padding: 0; font-size: .92rem; }
.bench-holds li { position: relative; padding-left: 1.5rem; margin: 0 0 .35rem; }
.bench-holds li::before {
  content: ""; position: absolute; left: 0; top: .62em;
  width: .45rem; height: .45rem; background: var(--state); border-radius: 1px;
}
.bench-floor { font-size: .84rem; color: var(--dim); margin: 0 0 1.5rem; }

details.bench-table { margin: 0 0 1rem; }
details.bench-table summary {
  display: flex; align-items: center; min-height: 44px;
  cursor: pointer; font-weight: 650; font-size: .92rem;
}

@media (max-width: 34rem) {
  .row, .axis { grid-template-columns: 1fr; gap: .35rem; }
  .track-label { text-align: left; }
  .axis { display: none; }
  .hero { gap: 1rem; }
  .appicon { width: 64px; height: 64px; }
  /* Let a row label wrap here. Holding it on one line costs the value column
     the width a 64-character SHA-256 needs most on a phone. */
  tbody th { white-space: normal; }
}

/* The version a legal page describes. Small and quiet: it is a provenance
   note, not a heading, and it must not compete with the text above it. */
.stamp {
  font-size: 0.85rem;
  opacity: 0.7;
  margin-top: 2rem;
}
