/* ==========================================================================
   shared/base.css — the rules the whole collection agrees on.

   Sixteen atlases were built at different times by different hands. Each one
   arrived with its own palette, its own type scale and its own idea of where a
   phone stops being a laptop — and that is fine, because the palette and the
   type scale are what make an atlas itself. What was not fine is that they also
   disagreed about things a reader can feel but not name: whether the scrollbar
   matches the page, whether a phone scrolls sideways, whether a control is big
   enough to hit with a thumb, whether motion stops when the reader asked it to.

   This file settles exactly those. It is loaded LAST on every page, after the
   atlas's own stylesheet, so it can settle a disagreement rather than lose one.
   That is a loaded weapon, so it is used with a rule:

       Anything an atlas should still be free to decide is written inside
       :where(), which has zero specificity — it is a default the atlas
       overrides just by mentioning the selector at all. Anything written at
       normal specificity is deliberate, and the comment above it says why.

   Nothing here sets a colour, a font or a size that belongs to an atlas.
   ========================================================================== */


/* ── 1. one set of breakpoints ─────────────────────────────────────────────
   Between them the sixteen atlases used fourteen breakpoints — 560, 620, 640,
   720, 760, 820, 860, 900, 1000, 1024, 1080, 1100, 1140, 1180, 1240, 1300 — so
   two atlases side by side would reflow at different widths and a reader
   dragging a window watched the collection come apart in stages.

   Everything shared uses three, and new work should too:

       --bp-phone    640px   one column; the rail is gone or off-canvas
       --bp-tablet   900px   the rail collapses, the detail pane takes over
       --bp-laptop  1180px   the rail narrows but stays

   A custom property cannot be used inside a media query, so these are recorded
   as a convention that the media queries below spell out literally. They are
   declared as properties anyway because script and container queries can read
   them, and because a number written down once is a number that stays agreed.
   ── */
:root {
  --bp-phone: 640px;
  --bp-tablet: 900px;
  --bp-laptop: 1180px;
}


/* ── 2. the box model, everywhere, without exception ───────────────────────
   All sixteen already declared this. It is repeated here so that anything
   added later — a widget, an embed, a page written in a hurry — inherits it
   without having to remember. ── */
*, *::before, *::after { box-sizing: border-box; }


/* ── 3. text that does not resize itself ───────────────────────────────────
   Mobile Safari inflates the type in a narrow column when the phone turns
   sideways, which pulls a carefully set measure apart. Every atlas here sets
   its own measure. ── */
:where(html) {
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
}


/* ── 4. one theme, down to the browser's own furniture ─────────────────────
   chrome.js decides dark or light and writes html[data-theme] while the page
   is still parsing, so the palette is settled before first paint. But a
   palette is only the part of the page the stylesheet draws. The scrollbars,
   the <select> drop-down, the text-field caret and border, the rubber-band
   gutter past the end of a scroll, the spell-check underline — those are the
   browser's, and the browser paints them from `color-scheme`, not from the
   page's colours.

   Five of the sixteen atlases declared color-scheme. The other eleven left it
   at the OS default, so a reader on a dark Mac who chose light got a bright
   page with dark scrollbars and a black drop-down; a reader on a light Mac who
   chose dark got the reverse. It is the single most visible way the collection
   failed to look like one collection.

   Bound here, once, at normal specificity so it wins over any atlas that
   declared its own default the other way round — harmony's :root, for
   instance, is light, because harmony was authored light-first.
   ── */
html[data-theme="dark"]  { color-scheme: dark; }
html[data-theme="light"] { color-scheme: light; }
/* chrome.js always sets the attribute; this is for the moment before it runs,
   and for the reader whose extension blocked the script entirely. */
html:not([data-theme]) { color-scheme: dark light; }


/* ── 5. no page scrolls sideways ───────────────────────────────────────────
   `clip`, not `hidden`. `overflow: hidden` on the root turns it into a scroll
   container, and a scroll container breaks every `position: sticky` group
   header in the collection — the list headings in harmony, jazz and kpop all
   depend on one. `clip` refuses the overflow without creating the container.

   This is a backstop, not a licence: a pane that overflows is still a bug, and
   §6 exists so that it doesn't. But the backstop means the bug reads as a
   clipped edge rather than as a page the reader can drag off-centre.
   ── */
html, body { overflow-x: clip; }


/* ── 6. the flex and grid blowout, which is where the sideways scroll comes from
   A grid or flex item's automatic minimum size is not zero — it is the
   min-content width of what is inside it. So one unbreakable thing anywhere in
   a pane (a long mono string, a fixed-width control, a chord grid, a table)
   makes the whole pane refuse to shrink below it, and the page scrolls
   sideways with no element visibly at fault. The modes atlas did exactly this:
   at a 390px viewport its detail pane measured 438px and the page dragged 48px
   to the right, and nothing in the detail looked wrong.

   The panes are named rather than fixed with a blanket `* { min-width: 0 }`,
   because a blanket rule also collapses the flex items that are *supposed* to
   size to their content — a nav that should not wrap, a fixed-width rail.
   These are the shell containers and scroll panes the sixteen atlases use;
   they all either carry an explicit width or are meant to fill what is left,
   so none of them wants an automatic minimum.
   ── */
.app, .shell, .layout, .body, .stage, .panes, .cols, .wrap,
.pane, .pane-list, .pane-detail, .detail, .page, .list, .rail,
.stage-inner, .detail-inner, .d-inner, .pane-in, .dwrap, .view,
#root, #app, #stage, #stageInner, #detail, #detailPane, #paneDetail,
#pane, #dbody, #list, #viewStyle {
  min-width: 0;
}

/* The same automatic minimum applies down the block axis, and it is why a
   flex column whose child should scroll instead grows past the viewport and
   takes the whole page with it. Only the columns are named. */
.app, .shell, .layout, .body, .stage, .panes {
  min-height: 0;
}


/* ── 7. controls a thumb can actually hit ──────────────────────────────────
   These atlases were designed at a desk, at mouse precision: measured at a
   390px viewport, the electronic atlas alone offers 273 controls under 32px
   tall, and every atlas offers some. Rather than redraw sixteen headers, the
   floor is applied only where the pointer is coarse, so the desktop keeps its
   tight density and the phone gets something hittable. min-height rather than
   height, so a control that is already comfortable is left exactly as it was.

   The collection chrome is deliberately excluded: its pill is a fixed 31px on
   a narrow screen and the buttons are sized to sit inside it, so a floor here
   would push them through their own container. chrome.css raises the whole
   cluster instead.
   ── */
@media (pointer: coarse) {
  button:not(.mac-btn),
  [role="button"],
  select,
  summary,
  input[type="checkbox"],
  input[type="radio"] {
    min-height: 32px;
  }
  /* a text input a thumb can land in, and — at 16px — one that does not make
     iOS zoom the whole page in when it takes focus */
  input[type="text"], input[type="search"], input:not([type]), textarea {
    min-height: 36px;
    font-size: max(16px, 1em);
  }
}


/* ── 8. the fixed chrome, clear of the hardware ────────────────────────────
   .mac-home and .mac-tools are pinned to the top corners. On a notched phone
   held sideways, the top corners are where the sensor housing is. ── */
@supports (padding: env(safe-area-inset-left)) {
  .mac-home  { left:  max(12px, env(safe-area-inset-left)); }
  .mac-tools { right: max(12px, env(safe-area-inset-right)); }
  @media (max-width: 640px) {
    .mac-home  { left:  max(8px, env(safe-area-inset-left)); }
    .mac-tools { right: max(8px, env(safe-area-inset-right)); }
  }
}


/* ── 9. one focus ring ─────────────────────────────────────────────────────
   Four atlases drew a proper focus ring, the rest inherited whatever the
   browser does — which, once a stylesheet has restyled the control, is often
   nothing at all. currentColor rather than an accent, so the ring picks up
   whatever the focused thing is already coloured and stays visible in both
   themes without this file knowing a single palette.

   Inside :where(), so an atlas with its own ring keeps it.
   ── */
:where(a, button, input, select, textarea, summary, [tabindex]):focus-visible {
  outline: 2px solid currentColor;
  outline-offset: 2px;
}


/* ── 10. motion stops when the reader asked it to ──────────────────────────
   Five atlases honoured prefers-reduced-motion; eleven did not, and several of
   those animate on every route change. The duration is near-zero rather than
   `none` so that animationend and transitionend listeners still fire — an
   atlas that reveals a pane in that handler must not be left with the pane
   hidden forever. ── */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
    scroll-behavior: auto !important;
  }
  html { scroll-behavior: auto !important; }
}


/* ── 11. print ─────────────────────────────────────────────────────────────
   Nothing here tries to make sixteen app shells print well. It removes the
   furniture that is certainly wrong on paper and lets the text through. ── */
@media print {
  html, body { overflow: visible !important; height: auto !important; }
  .mac-home, .mac-tools { display: none !important; }
  :where(.rail, .pane-list, .list, nav, .scrim, .sheet) { display: none !important; }
  :where(.detail, .pane-detail, .stage, .page, .body, .app, .shell) {
    overflow: visible !important;
    height: auto !important;
    max-height: none !important;
  }
}
