/* ============================================================
   LEXUN — the premium layer
   ------------------------------------------------------------
   This file exists because of load order, not because the rules in it
   are a different kind of rule. /css/lexun.*.css is the base and every
   page links it FIRST, so hud, deck, ctl and dash all legitimately
   override it. A handful of decisions have to hold everywhere regardless
   of which of those a page happens to load — the reading size of body
   text, the measure of a paragraph, the radius of a panel, where the one
   accent is allowed to appear — and the only honest way to make a rule
   hold last is to load it last. So this sheet is linked after every other
   stylesheet on every page, it is short on purpose, and nothing in it
   uses !important: source order does the work.

   If a rule in here duplicates one in lexun.css, that is a sign the
   component underneath should be fixed instead. The list should shrink.
   ============================================================ */

/* ---------- reading ---------------------------------------------------
   15px body text is a density decision that made sense when this was a
   dashboard and stopped making sense when it became something people read
   paragraphs on. 17px at 1.65 is the size an argument gets read at rather
   than skimmed. The measure comes down with it: 66ch is the top of the
   comfortable range, and the site had paragraphs running to 74. */
body{font-size:17px;line-height:1.65}
p,li,dd{text-wrap:pretty}
p{max-width:66ch}
h1,h2,h3,h4,h5,h6{text-wrap:balance}

/* A heading that is also a machine readout is a heading first. */
h1,h2,h3,h4,h5,h6{font-family:var(--sans)}

/* ---------- surface ---------------------------------------------------
   4px on a hairline box is the radius you get by not choosing one. The
   panel radius is now 12px (--r) and controls sit one step tighter at 8px
   (--r-s), so a control never looks softer than the panel holding it.

   The inner top highlight is the whole trick: a 1px line of 9% white
   along the top edge reads as a light source above the page, which is
   what makes a flat dark rectangle look like a physical surface rather
   than a div with a border. The ambient shadow is deliberately huge and
   nearly transparent — it separates the card from the black without ever
   being visible as a shadow. */
.card,.panel,.lx-card,.pane,.tile{
  border-radius:var(--r);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.09), 0 24px 60px -40px rgba(0,0,0,.95);
}
.lxlight .card,.lxlight .panel,.lxlight .lx-card,.lxlight .pane,.lxlight .tile{
  box-shadow:inset 0 1px 0 rgba(255,255,255,.9), 0 24px 60px -44px rgba(0,0,0,.22);
}
input,select,textarea,.btn,.btn-primary,.btn-ghost,button.primary,.btn.primary,.btn.ghost{
  border-radius:var(--r-s);
}
.chip-status,.chip,.badge,[class*="pill"]{border-radius:var(--r-full)}

/* ---------- the accent ------------------------------------------------
   One colour, three jobs: the thing you can press, the thing that is
   live, and the band the engine is uncertain across. Nothing else.
   State stays with --good/--warn/--bad, and no viewport is allowed to
   show the accent for two different reasons at once. */
:focus-visible{outline:2px solid var(--acc2);outline-offset:2px}
a:not(.btn):not(.btn-primary):not(.btn-ghost):not(.chip):not(.navbtn):hover{color:var(--acc)}
::selection{background:var(--acc);color:var(--ink-on-acc)}

/* ---------- grain -----------------------------------------------------
   A large field of #000 on an OLED phone is not black, it is a surface with
   visible banding wherever a gradient crosses it, and on an LCD it is flat in
   a way that reads as cheap. Two percent of monochrome fractal noise over the
   whole page kills the banding and gives the black a grain you feel rather
   than see.

   It lived in lexun.css until /second.html turned out to be the one page in
   the site that does not link lexun.css — it carries its own small token
   block and only ctl.css. Rather than bolt the base sheet onto that page and
   restyle it by accident, the grain moved to the one sheet every page really
   does load. Measured, not assumed: the harness checks all 35 pages for it.

   Constraints it has to meet: it must not intercept a click, must not be
   readable by assistive technology, must not be the reason a page paints
   late, and must not print. It is an ::after on the root element rather than
   an extra <div>, so it costs nothing in markup and needs no per-page edit.
   The SVG is a data: URI — part of the stylesheet, no extra request, nothing
   fetched from a third party. The 200x200 tile repeats, and feTurbulence is
   evaluated once by the rasteriser and cached as an image, so this is not a
   per-frame cost. */
html::after{
  content:"";position:fixed;inset:0;z-index:2147483000;pointer-events:none;
  opacity:.02;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='200' height='200'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.82' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='200' height='200' filter='url(%23n)'/%3E%3C/svg%3E");
  background-size:200px 200px;
}
@media print{html::after{display:none}}

/* ---------- motion ----------------------------------------------------
   Two durations and one curve, restated here so a component sheet cannot
   quietly introduce a third. Anything that is a response to a person
   finishes inside 600ms; ambient loops are exempt and are handled by the
   reduced-motion block in lexun.css. */
@media (prefers-reduced-motion:no-preference){
  .btn,.btn-primary,.btn-ghost,.btn.primary,.btn.ghost,.chip,.navbtn,input,select,textarea{
    transition-duration:var(--fast);
    transition-timing-function:var(--ease);
  }
}

/* ---------- carousel pagination ---------------------------------------
   A card clipped at the right edge with no indicator does not read as a
   carousel, it reads as a broken grid. The eight per cent peek and the snap
   points were already right; what was missing was the answer to "how many"
   and "where am I". These dots supply both.

   They are inserted by carousel.js only when a container genuinely scrolls,
   so nothing here is tied to a breakpoint — the strip is present on a phone
   and absent on the desktop grid because the measurement says so, not
   because a media query guessed.

   The button is 24x24 including its padding, which is the WCAG 2.2 target
   size (2.5.8); the visible dot is 8px because a 24px dot would be a
   different design. Position is carried by aria-current, and by scale as
   well as colour, so it never depends on hue alone. */
.cdots{display:flex;align-items:center;gap:0;margin:0 0 10px;padding:0;flex-wrap:wrap}
.cdots[hidden]{display:none}
.cdots>button{
  appearance:none;-webkit-appearance:none;background:none;border:0;margin:0;
  width:24px;height:24px;padding:8px;line-height:0;cursor:pointer;
  display:inline-flex;align-items:center;justify-content:center;
}
.cdots>button::before{
  content:"";display:block;width:8px;height:8px;border-radius:50%;
  background:var(--line2,rgba(255,255,255,.34));
}
.cdots>button[aria-current="true"]::before{background:var(--acc);transform:scale(1.25)}
@media(hover:hover){ .cdots>button:hover::before{background:var(--acc-hi,var(--acc))} }
.cdots>button:focus-visible{outline:2px solid var(--acc2);outline-offset:1px;border-radius:50%}
@media (prefers-reduced-motion:no-preference){
  .cdots>button::before{transition:background var(--fast) var(--ease),transform var(--fast) var(--ease)}
}

/* ── the shared announcer, and the panels tabs.js hides ────────────────────
   Both of these belong here rather than on a page, because tabs.js is loaded
   on all thirty-five pages and second.html is the one page that does not link
   lexun.css. A rule that must hold everywhere has exactly one home.

   .lxsr is what the announcer tabs.js appends to <body> wears. Without it
   that paragraph is not a screen-reader-only status region, it is a visible
   line of text at the foot of the page saying "Region focus: Europe".
   clip-path as well as clip because clip is deprecated, and white-space
   because a collapsed 1px box otherwise wraps its text to one character per
   line, which some screen readers read out letter by letter. */
.lxsr{
  position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;
  clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap;border:0;
}

/* [hidden] is a user-agent rule at the very bottom of the cascade, so any
   author display declaration beats it — and several of this site's panels
   inherit display:grid or display:flex from a layout rule. tabs.js hides a
   panel by setting the hidden property, so the sheet that ships alongside it
   has to make that property mean something. */
[role="tabpanel"][hidden],[data-lxpanel][hidden]{display:none!important}


/* ── the command surface ──────────────────────────────────────────────────
   The instrument's mouthpiece: every place a person types a decision — the
   hero Analyse box, the workspace question, the assistant, the Earth's fly
   search. One treatment across all of them: glass depth with a hairline top
   light, a caret in the accent, and a focus state that arrives as a ring of
   the one colour this site reserves for interactive affordances. */
.cmdrow input,#homeQ,#askIn,#flyQ,#fStatement{
  background:linear-gradient(180deg,rgba(255,255,255,.075),rgba(255,255,255,.035));
  border:1px solid rgba(255,255,255,.16);
  border-radius:12px;
  box-shadow:inset 0 1px 0 rgba(255,255,255,.07);
  caret-color:var(--acc,#5b9dff);
  transition:border-color .18s cubic-bezier(.22,.61,.36,1),box-shadow .18s cubic-bezier(.22,.61,.36,1);
}
.cmdrow input:hover,#homeQ:hover,#askIn:hover,#flyQ:hover,#fStatement:hover{border-color:rgba(255,255,255,.28)}
.cmdrow input:focus,#homeQ:focus,#askIn:focus,#flyQ:focus,#fStatement:focus,
.cmdrow input:focus-visible,#homeQ:focus-visible,#askIn:focus-visible,#flyQ:focus-visible,#fStatement:focus-visible{
  outline:none;border-color:var(--acc,#5b9dff);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.07),0 0 0 3px rgba(91,157,255,.20),0 6px 30px -12px rgba(91,157,255,.35);
}
.cmdrow input::placeholder,#homeQ::placeholder,#askIn::placeholder,#flyQ::placeholder,#fStatement::placeholder{color:rgba(174,174,174,.66)}

/* the Analyse button: it lifts to meet the hand, presses under it, and its
   arrow leans into the journey — 180ms, compositor-only, nothing over 420ms */
.cmdrow .btn.primary{
  border-radius:12px;
  transition:transform .18s cubic-bezier(.22,.61,.36,1),box-shadow .18s cubic-bezier(.22,.61,.36,1),background .18s cubic-bezier(.22,.61,.36,1);
}
.cmdrow .btn.primary:hover{
  transform:translateY(-1px);
  box-shadow:0 8px 28px -10px rgba(91,157,255,.55),0 2px 8px -2px rgba(0,0,0,.6);
}
.cmdrow .btn.primary:active{transform:translateY(1px);box-shadow:none}
.cmdrow .btn.primary .ar{display:inline-block;transition:transform .18s cubic-bezier(.22,.61,.36,1)}
.cmdrow .btn.primary:hover .ar{transform:translateX(3px)}

/* the example chips: precision pills. Each carries, once the engine is warm,
   the band it would return — computed live in this browser from the same
   frozen models, which is why the number may wear the accent: it is a
   probability band, the one figure that colour belongs to. */
#heroEx button[data-q],.cmdex button{
  border-radius:999px;padding:6px 13px;min-height:30px;
  background:linear-gradient(180deg,rgba(255,255,255,.09),rgba(255,255,255,.05));
  border:1px solid rgba(255,255,255,.22);
  transition:border-color .18s cubic-bezier(.22,.61,.36,1),transform .18s cubic-bezier(.22,.61,.36,1),background .18s cubic-bezier(.22,.61,.36,1);
}
#heroEx button[data-q]:hover,.cmdex button:hover{border-color:var(--acc,#5b9dff);transform:translateY(-1px);background:rgba(255,255,255,.12)}
#heroEx button[data-q]:active,.cmdex button:active{transform:translateY(0)}
#heroEx button .bnd,.cmdex button .bnd{
  font-family:var(--mono,ui-monospace,monospace);font-size:10px;font-variant-numeric:tabular-nums;
  color:var(--acc,#5b9dff);margin-left:7px;opacity:0;transition:opacity .42s cubic-bezier(.22,.61,.36,1);
}
#heroEx button .bnd.on,.cmdex button .bnd.on{opacity:1}

/* ── the scrub: sensitivity you can hold ──────────────────────────────────
   The slider takes the accent because it is an interactive affordance; the
   result beside it is a probability band, the other thing the accent is for.
   The row is honest by construction — the word "modelled" travels with the
   number, in the machine voice, because a scrubbed run is an experiment. */
.adrv .d .scrub{grid-column:1/-1;display:flex;gap:10px;align-items:center;margin:1px 0 5px}
.adrv .d .scrub input[type=range]{flex:1;min-width:0;accent-color:var(--acc,#5b9dff);min-height:24px;cursor:ew-resize}
.adrv .d .scrub .sout{font-family:var(--mono,ui-monospace,monospace);font-size:10px;font-variant-numeric:tabular-nums;color:var(--acc,#5b9dff);min-width:13ch;text-align:right;white-space:nowrap}
.adrv .snote{margin:6px 0 0;font-size:10.5px;color:var(--dim,#919191);letter-spacing:.02em}

/* the workspace scrub rows share the homepage geometry */
#sensScrub{display:grid;gap:4px;margin-top:10px}
#sensScrub .d{display:grid;grid-template-columns:1fr;gap:2px;font-size:12px;color:var(--mut,#aeaeae)}

/* the workspace fan and the preview badge */
#wsFan{display:block;width:100%;height:120px}
#livePrev{color:var(--acc,#5b9dff);font-variant-numeric:tabular-nums}
