/* cfw-release.css — the ASK-local release layer.
 *
 * THE ROUTE IS TWO PAGES. The conclusions are an ORDINARY SHELL PAGE at the
 * route root and consume surface-shell like every other subpage; the MAP, one
 * level deeper, is the retained fixed full-viewport application and remains the
 * shell exception. Both load this file, so it carries the map layer, the
 * conclusions layer, and the responsive contract for both.
 *
 * The former orientation overlay's three footer destinations were this route's
 * only consumers of the root-vendored surface-text-link.css; the shell footer
 * now carries those destinations as compact actions. With the overlay retired
 * neither page has a `.surface-text-link` element left, so NEITHER PAGE LINKS
 * THE MODULE any more. The root-vendored file itself stays where it is — other
 * subpages consume it.
 *
 * The engine's own stylesheet (cfw-atlas.css) came from the approved internal
 * package; the engine and that stylesheet are maintained in this repo and are no
 * longer byte-identical to it. This file edits neither. It adds only what the
 * public release needs: the ASK wordmark in the bar, the conclusions layer, and
 * the responsive contract. It defines NO token: every color, size and spacing
 * value below resolves to a design-system-ASK custom property.
 *
 * RESPONSIVE CONTRACT
 *   wide    >= 1024   full interactive map + atlas; the conclusions are a link
 *   tablet  768-1023  full map; legend and caption collapsed by default
 *   small   <  768    the map keeps its two-row application bar and opens with
 *                     the inspector collapsed to a pill, as a touch screen at
 *                     most 520px tall also does; opening a record expands the
 *                     inspector as a sheet across the top. The conclusions are
 *                     a separate route rather than a landing overlay, so a
 *                     small screen reaches them by navigating, not by a mode.
 *   every   width     one finger pans, two fingers pinch around the fingers, a
 *                     tap selects, and Fit keeps the drawing's extent clear of
 *                     the chrome it reserves
 */

/* ---- ASK wordmark in the engine bar ------------------------------------- */
/* Both marks are img children of .rel-mark, so the geometry rule must NOT set
   `display` — at (0,1,1) it would outrank the (0,1,0) swap selectors and paint
   both. Geometry here, visibility on the mode selectors only. */
.rel-mark { display: inline-flex; align-items: center; height: 22px; flex: none; }
.rel-mark img { height: 100%; width: auto; }
.rel-mark .rel-mark-light { display: block; }
.rel-mark .rel-mark-dark  { display: none; }
@media (prefers-color-scheme: dark) {
  .rel-mark .rel-mark-light { display: none; }
  .rel-mark .rel-mark-dark  { display: block; }
}
html[data-theme="dark"]  .rel-mark .rel-mark-light { display: none; }
html[data-theme="dark"]  .rel-mark .rel-mark-dark  { display: block; }
html[data-theme="light"] .rel-mark .rel-mark-light { display: block; }
html[data-theme="light"] .rel-mark .rel-mark-dark  { display: none; }

/* ---- conclusions: the payload inside the vendored shell -----------------
   The conclusions are no longer a fixed overlay; they are the route root's own
   page, laid out inside `<main class="surface-payload">`. The shell declares no
   payload layout by contract, so the reading measure is this route's to set —
   and it is the SAME 68ch the orientation carried, so the split changes where
   the conclusions live without changing how they read.

   No padding and no auto margin here: `.surface` already owns the page's edge
   inset and its own centring, and a second set would inset the payload twice.
   Everything below — .orient-status, .orient-prose, .orient-h, .rulings,
   .counts, .orient-search, .orient-results, .askc* — is shared with the former
   overlay and is unchanged by the split. These are the surviving CONTENT roles,
   and they keep the historical `orient-` prefix deliberately: renaming a
   working selector to tidy a prefix is churn, not a repair. The LAYER those
   roles used to sit in carried its own chrome; that chrome is gone, along with
   the machinery in cfw-release.js that drove it. */
.cfw-conclusions { max-width: 68ch; }

.orient-status { display: flex; flex-wrap: wrap; gap: var(--space-2); margin: 0 0 var(--space-5); }
.orient-status .tag {
  font-family: var(--font-mono); font-size: var(--fs-caption); font-weight: var(--fw-light);
  letter-spacing: var(--tracking-normal); text-transform: uppercase;
  color: var(--fg-2); border: 1px solid var(--line-2);
  border-radius: var(--radius-pill); padding: 2px var(--space-3);
}
.orient-prose p, .orient-note { color: var(--fg-2); line-height: var(--lh-body); }
.orient-prose p { margin: 0 0 var(--space-4); color: var(--fg-1); }
.orient-note { font-size: var(--fs-small); margin: 0 0 var(--space-4); }
.orient-h {
  font-family: var(--font-mono); font-size: var(--fs-caption); font-weight: var(--fw-light);
  letter-spacing: var(--tracking-wide); text-transform: uppercase;
  color: var(--fg-2); margin: var(--space-6) 0 var(--space-3);
}

/* ---- the six rulings ---------------------------------------------------- */
.rulings { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--space-4); }
.rulings li { border: 1px solid var(--line-2); border-radius: var(--radius-2); padding: var(--space-4); }
.rulings .rq {
  font-family: var(--font-mono); font-size: var(--fs-caption);
  color: var(--fg-3); letter-spacing: var(--tracking-normal);
}
.rulings .rtitle {
  display: block; margin: var(--space-2) 0; color: var(--fg-1);
  font-size: var(--fs-body); line-height: var(--lh-heading);
}
.rulings .rdisp {
  display: inline-block; font-family: var(--font-mono); font-size: var(--fs-caption);
  text-transform: uppercase; letter-spacing: var(--tracking-normal);
  color: var(--fg-2); border: 1px solid var(--line-2);
  border-radius: var(--radius-pill); padding: 1px var(--space-3); margin-bottom: var(--space-3);
}
.rulings dl { margin: 0; display: grid; grid-template-columns: max-content 1fr; gap: var(--space-2) var(--space-3); }
.rulings dt {
  font-family: var(--font-mono); font-size: var(--fs-caption); text-transform: uppercase;
  letter-spacing: var(--tracking-normal); color: var(--fg-3); white-space: nowrap;
}
.rulings dd { margin: 0; color: var(--fg-2); font-size: var(--fs-small); line-height: var(--lh-body); }
.rulings .ask-note { margin-top: var(--space-3); font-size: var(--fs-caption); color: var(--fg-3); }

/* ---- counts ------------------------------------------------------------- */
.counts { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--space-2); }
.counts li { display: flex; gap: var(--space-3); align-items: baseline; }
.counts .n {
  font-family: var(--font-mono); font-size: var(--fs-body); color: var(--fg-1);
  min-width: 5ch; text-align: right;
}
.counts .w { color: var(--fg-2); font-size: var(--fs-small); }

/* ---- search ------------------------------------------------------------- */
.orient-search input {
  width: 100%; box-sizing: border-box;
  font-family: var(--font-mono); font-size: var(--fs-small); color: var(--fg-1);
  background: transparent; border: 1px solid var(--line-2);
  border-radius: var(--radius-2); padding: var(--space-3);
}
.orient-search input:focus-visible { outline: 2px solid var(--fg-2); outline-offset: 2px; }
/* Browser-native search clear control // retain its behavior, replace the platform
   paint with ASK-owned tokens. The mark is drawn from two token-coloured diagonals,
   so this surface owns its pixels instead of inheriting the platform default. */
.orient-search input[type="search"]::-webkit-search-cancel-button {
  -webkit-appearance: none;
  appearance: none;
  width: 12px;
  height: 12px;
  margin-inline-start: var(--space-2);
  cursor: pointer;
  opacity: 0.68;
  background:
    linear-gradient(
      45deg,
      transparent 46%,
      var(--fg-2) 46%,
      var(--fg-2) 54%,
      transparent 54%
    ),
    linear-gradient(
      -45deg,
      transparent 46%,
      var(--fg-2) 46%,
      var(--fg-2) 54%,
      transparent 54%
    );
  background-repeat: no-repeat;
}
.orient-search input[type="search"]::-webkit-search-cancel-button:hover {
  opacity: 1;
}
.orient-results { margin-top: var(--space-3); display: flex; flex-direction: column; gap: var(--space-2); }
.orient-results .ores-r {
  border: 1px solid var(--line-2); border-radius: var(--radius-2);
  padding: var(--space-3); font-size: var(--fs-small); color: var(--fg-2);
}
.orient-results .ores-id {
  font-family: var(--font-mono); font-size: var(--fs-caption); color: var(--fg-3);
  display: block; margin-bottom: 2px;
}
.orient-results .ores-meta { display: block; margin-top: 4px; color: var(--fg-3); font-size: var(--fs-caption); }
.orient-results .ores-none { color: var(--fg-3); font-size: var(--fs-small); }

/* ---- the action into the map -------------------------------------------- */
.orient-enter { margin-top: var(--space-6); }
.orient-enter .orient-note { margin-top: var(--space-3); }
/* The top instance carries no note, so it needs the separation the note would
   have given it. One declaration: the inherited top margin already collapses
   against the status row above, and this restores the same rhythm below, so
   both actions sit in an identical space-6 gutter. */
.orient-enter--top { margin-bottom: var(--space-6); }

/* The three application-bar controls as one composition group. On a wide screen
   this must be invisible: the bar already sets an 18px gap between its own
   children, so the group reproduces that value internally and the rendered
   geometry is unchanged from a flat row.
   DECLARED BEFORE THE MEDIA QUERIES DELIBERATELY. The small-screen rule below
   restates this selector at equal specificity, so source order is what decides
   it — a base rule placed after the query would silently win and the two-row
   composition would never apply. */
.bar .bar-actions { display: flex; align-items: center; gap: 18px; min-width: 0; }

/* ---- HUD: the two PNG export controls -----------------------------------
   PLACEMENT ONLY. `.hud button` is sized for a 30px glyph square, and these two
   carry words, so they need a text box rather than that square. They sit in the
   HUD's own mono register beside `regions` and `no filter` — one step brighter,
   because unlike those two they are actionable rather than reportorial. The
   label case is authored, not transformed: `PNG page` is the control's name.

   THE PAIR IS A SECOND ROW, PLACED OUT OF FLOW, and the reason is measured.
   Inline, these two labels widen the HUD from 304px to 482px and run it under
   the centred caption panel that shares its bottom edge — 60px at 1440, 140px
   at 1280, 244px at 1024. Making the HUD a two-row flex container fixes the
   width and not the harm: the HUD grows upward, the caption spans that band,
   and the obscured caption area at 1024 goes 2,895.64 -> 4,869.94 px^2, a 68%
   regression that a width-only check calls clean.

   Out of flow, the HUD's own box stays 304x44 and its caption overlap is
   exactly the baseline's; the export row is ~175px wide against a caption
   starting at x=256, so it adds none of its own. It carries its own glass
   because it is visually a second pill, not a detached strip. At 320px it is
   still far inside the viewport, so no third row and no clipping. */
.hud .hud-row-export {
  position: absolute; left: -1px; bottom: calc(100% + 7px);
  display: flex; align-items: center; gap: 4px; flex-wrap: nowrap;
  padding: 5px 6px;
  background: var(--surface-glass);
  -webkit-backdrop-filter: blur(20px); backdrop-filter: blur(20px);
  border: 1px solid var(--surface-glass-2);
  border-radius: var(--radius-md);
}
.hud .hud-export {
  width: auto; height: 26px; padding: 0 9px;
  font-family: var(--font-mono); font-size: 9.5px; letter-spacing: 0.08em;
  color: var(--fg-2); white-space: nowrap;
}
.hud .hud-export:hover { color: var(--fg-1); background: var(--surface-glass-2); }
.hud .hud-export[disabled] { opacity: 0.55; cursor: default; }

/* ---- tablet: overlays collapsed by default ------------------------------ */
@media (max-width: 1023px) and (min-width: 768px) {
  .cfw-caption { display: none; }
  .legend { display: none; }
  body[data-overlays="1"] .cfw-caption,
  body[data-overlays="1"] .legend { display: block; }
}

/* ---- small screen: orientation is the landing surface ------------------- */
@media (max-width: 767px) {
  .cfw-caption, .legend { display: none; }
  .bar .stamp { display: none; }
  .bar .title-block .s { display: none; }

  /* ---- explicit two-row application bar ---------------------------------
     Below 768px the mark, the title and three compact actions cannot share one
     row: measured against production, `atlas` already sits 5px past the right
     edge at 390 and 75px past it at 320, and the theme selector is 107px and
     177px past it. `body { overflow: hidden }` is why that never announced
     itself as a scrollbar — the row simply runs off the surface and is clipped.
     Conforming the two controls to the compact-action contract makes them wider
     still, so the placement has to be fixed for the visual correction to mean
     anything.

     This is an EXPLICIT composition, not natural wrapping. `.bar-actions` is
     forced to a full-width second row, so the split always falls in the same
     place and the control order never depends on the viewport. Letting the flex
     row wrap on its own would reorder controls between widths.

     Row layout, placement and gap are the consuming surface's to own — the
     vendored action contract deliberately governs the control and not the row —
     so this lives here rather than upstream. */
  .bar { flex-wrap: wrap; row-gap: var(--space-2); }
  .bar .spacer { display: none; }
  .bar .title-block { flex: 1 1 auto; min-width: 0; }
  .bar .bar-actions {
    flex: 0 0 100%;
    display: grid;
    grid-template-columns: minmax(0, 1fr) max-content max-content;
    gap: var(--space-2);
    min-width: 0;
  }
  /* The long label takes the flexible column and wraps inside its own pill at the
     narrowest widths. The contract sets `white-space: normal` precisely so a long
     label wraps rather than forcing overflow — do not add nowrap here. */
  .bar .bar-actions .bar-conclusions { width: 100%; min-width: 0; }
  .rulings dl { grid-template-columns: 1fr; gap: var(--space-1) 0; }
  .rulings dt { margin-top: var(--space-2); }

  /* the map's inspector: a sheet across the top while expanded, a pill at the top
     right while collapsed; inset past the canvas corner ticks */
  .inspector { top: var(--space-5); right: var(--space-5); left: var(--space-5);
               width: auto; max-height: 46%; }
  body.insp-collapsed .inspector { left: auto; }
}
/* The former `@media (min-width: 768px) { .orient-enter { display: none } }` is
   RETIRED. It hid the bottom action above small because the map was already the
   surface behind the overlay. The map is a separate route now, so the action is
   the only route to it from this page and must be present at every width. */

/* ---- top-bar compact actions --------------------------------------------
   The two bar controls are COMPACT ACTIONS, not labels. design-system-ASK owns
   that contract in the vendored `surface-action.css`: JetBrains Mono, caption
   size, weight 300, sentence case, zero tracking, pill geometry, and the
   canonical hover / press / focus. The route previously painted them through
   `.bar .atlasbtn`, which is the Caption treatment — uppercase, tracked, and
   heavier — and the owner README names that conformance a defect rather than a
   repair. Adopting the class is therefore the repair; the block below owns ONLY
   what the shared contract deliberately does not: row placement, the atlas dot,
   and the active-filter expression. It restates no part of the contract, and it
   changes no foreground: `.surface-action` already resolves to --fg-1, which is
   exactly what these two controls carried before.
   `.bar .themer` keeps its own rule above — a mode selector is a different role
   and the shared contract explicitly excludes it. */
.bar .atlas-trigger { gap: var(--space-2); }
.bar .atlas-trigger .dot2 {
  width: 5px; height: 5px; border-radius: 50%;
  background: var(--fg-3); display: inline-block; flex: none;
}
/* An active filter is UI STATE, not a governed state, and it must stay inside the
   one compact-action grammar: no weight change, no uppercase, no second geometry.
   Foreground and the dot carry it. */
body.filtering .bar .atlas-trigger { border-color: var(--fg-1); }
body.filtering .bar .atlas-trigger .dot2 { background: var(--fg-1); }

/* ---- source links in the inspector --------------------------------------
   The inspector now renders locators as either a "source link" or a "citation",
   and both sit in the same monospace row. Underline carries that difference
   without introducing a colour token the design system does not define.
   Focus is already handled by `.inspector :focus-visible` in cfw-atlas.css. */
.inspector a.loc { color: var(--fg-1); text-decoration: underline;
                   text-underline-offset: 2px; text-decoration-thickness: 1px; }
.inspector a.loc:hover { color: var(--fg-high-contrast); }

/* ---- accessibility structure --------------------------------------------
   The bar title is the document's single h1 and the subtitle a paragraph, so
   neither may inherit the user agent's block margins inside the bar flex row.
   (The h1 previously lived inside the orientation surface, which is display:none
   above small — a wide screen reader met a page with no h1 at all.) */
.bar .title-block .t, .bar .title-block .s { margin: 0; }

/* Skip link: the first stop for a keyboard user, straight to this page's own
   payload. Visible only while focused. */
.skip {
  position: absolute; left: var(--space-3); top: var(--space-3); z-index: 100;
  transform: translateY(-200%);
  font-family: var(--font-mono); font-size: var(--fs-small);
  background: var(--ask-surface); color: var(--fg-1);
  border: 1px solid var(--line-1); border-radius: var(--radius-sm);
  padding: var(--space-2) var(--space-3); text-decoration: none;
}
.skip:focus { transform: none; outline: 2px solid var(--fg-1); outline-offset: 2px; }

/* Search results are controls: they open the record. On the map that is the
   inspector in this document; on the conclusions page it is the map, named. */
.orient-results button.ores-r {
  display: block; width: 100%; text-align: left; font: inherit; color: inherit;
  background: none; border: 0; cursor: pointer;
}
.orient-results button.ores-r:hover .ores-title { color: var(--fg-high-contrast); }
.orient-results button.ores-r:focus-visible { outline: 2px solid var(--fg-1); outline-offset: 2px; }

/* ---- theme selector -----------------------------------------------------
   Conformed to the design-system style guide's theme-selector grammar: a quiet
   lowercase mono caption in a glass pill, not the uppercase transparent chip the
   engine ships. ASK asked for the compact form, so the visible word "theme" is
   dropped and only the glyph and the current state show; the word survives as
   screen-reader-only text so the control still has a name rather than announcing
   a bare "auto". These override the vendored `.bar .themer` rule, which is not
   hand-edited here. */
.bar .themer {
  display: inline-flex; align-items: baseline; gap: var(--space-2);
  font-family: var(--font-mono); font-size: var(--fs-caption);
  letter-spacing: var(--tracking-normal);
  text-transform: none;                 /* quiet control — lowercase in every mode */
  color: var(--fg-2);
  background: var(--surface-glass);
  border: 1px solid var(--line-1);
  border-radius: var(--radius-pill);
  padding: var(--space-2) var(--space-4);
  cursor: pointer; white-space: nowrap;
  transition:
    opacity var(--dur-2) var(--ease-out),
    transform var(--dur-1) var(--ease-out);
}
.bar .themer:hover { opacity: 0.92; background: var(--surface-glass); }
.bar .themer:active { transform: scale(0.97); }
.bar .themer .themer-g { font-size: 1.05em; line-height: 1; }

/* ---- ASK conclusion ------------------------------------------------------
   Deliberately NOT styled like .rulings. A ruling is a survey disposition in a
   bordered card; this is ASK's own prose and must not be read as one. */
.askc { display: flex; flex-direction: column; gap: var(--space-4); }
.askc-intro { margin: 0; color: var(--fg-3); font-size: var(--fs-small); font-style: italic; }
.askc-pull, .askc-q {
  margin: 0; padding-left: var(--space-4); border-left: 2px solid var(--line-2);
  color: var(--fg-1); font-size: var(--fs-body); line-height: var(--lh-body);
}
.askc-sec { display: flex; flex-direction: column; gap: var(--space-3); }
.askc-h {
  margin: var(--space-4) 0 0; font-family: var(--font-mono); font-size: var(--fs-caption);
  text-transform: lowercase; letter-spacing: var(--tracking-normal); color: var(--fg-3);
}
.askc-p { margin: 0; color: var(--fg-2); font-size: var(--fs-small); line-height: var(--lh-body); }
.askc-ul { margin: 0; padding-left: var(--space-4); color: var(--fg-2); font-size: var(--fs-small); }
.askc-ul li { margin-bottom: var(--space-2); line-height: var(--lh-body); }
.askc-pre {
  margin: 0; padding: var(--space-3); overflow-x: auto;
  border: 1px solid var(--line-2); border-radius: var(--radius-2);
  font-family: var(--font-mono); font-size: var(--fs-caption);
  line-height: var(--lh-body); color: var(--fg-2); white-space: pre;
}
.askc-compress .askc-pull { color: var(--fg-1); }
.askc-error {
  margin: 0; padding: var(--space-3); color: var(--fg-2); font-size: var(--fs-small);
  line-height: var(--lh-body); border: 1px solid var(--line-2); border-radius: var(--radius-2);
}
