/* =============================================================================
   Airside Crew — the Screens page
   -----------------------------------------------------------------------------
   Built from apps/site/design/Screens.dc.html, which Dylan approved on Oct 27,
   2026 along with its five siblings (Screens-Night, Screens-Tablet,
   Screens-Tablet-Night, Screens-Mobile, Screens-Mobile-Night). Those five are
   the same file apart from the canvas preview size and the default theme —
   checked, not assumed; the diff is in
   docs/evidence/2026-10-28-step0.5-screens-shell.md. So every value below is
   Screens.dc.html's.

   WHY THIS IS A SEPARATE FILE AND NOT A SECTION OF site.css
   -----------------------------------------------------------------------------
   Task R4a was told not to open public/styles/site.css: another task was
   editing it at the same time, and the git index is shared state — a
   concurrent write loses one side or the other (docs/coding.md, "The git index
   is shared state"). So this page's own shell rules live here, and the page
   links this file AFTER site.css.

   WHAT GOES WHERE, and the test to apply:
     * site.css        — anything the shared shell already owns. Nothing new
                         was added to it by this task; the header, the footer,
                         the type scale, `.wrap`, `.page-hero`, `.emu-frame`,
                         `.emu-box` and `.emu-scale` were all already there and
                         are reused unchanged.
     * screens.css     — this page's own chrome: its hero, the gallery card,
                         the tab list, the Day/Night control, the caption
                         column and the onward card. Nothing here is inside a
                         depicted app screen.
     * mockups.css     — anything INSIDE a depicted app screen. This task added
                         one block there: the forced Day/Night palette, which
                         sets `--n-*` on `.emu` itself and therefore cannot
                         live anywhere else (see the note on it in that file).

   TWO LIMITS A READER SHOULD KNOW BEFORE TRUSTING A GREEN RUN
   -----------------------------------------------------------------------------
   1. src/html/motion.test.ts and src/html/animation-parity.test.ts scan
      site.css and mockups.css, and NOT this file. The gap is kept empty rather
      than left unguarded: there is no `@keyframes` and no `animation`
      shorthand below that names a new keyframe — the two animations used here
      (`hrSwap`, `hrSwapB`) are declared in site.css and already applied there,
      so neither scan's orphan tally changes. If a later task adds a keyframe
      to this file, add this file to those two SHEETS lists in the same commit.
   2. Section 25 of site.css is an `!important` reduced-motion backstop over
      every element and pseudo-element (`animation: none`, `transition: none`).
      It reaches this file because `!important` does not care about source
      order, so every transition below is cancelled for a visitor who asked for
      less motion, and no rule here hides anything on its own.
   ========================================================================== */

/* -----------------------------------------------------------------------------
   1. The hero
   -----------------------------------------------------------------------------
   `.page-hero` from site.css carries the navy, the ink and the clip. These are
   the four values Screens.dc.html gives its own hero that differ from the
   shared component: the two glows' size and position, the one-column inner
   with its 88px bottom padding, and the two text widths.
   -------------------------------------------------------------------------- */
.sc-hero__blob--a {
	width: 520px;
	height: 520px;
	right: -140px;
	top: -140px;
	background: rgba(4, 97, 248, 0.5);
}
.sc-hero__blob--b {
	width: 360px;
	height: 360px;
	left: -120px;
	bottom: -180px;
	background: rgba(4, 165, 248, 0.28);
	animation-duration: 20s;
}

.sc-hero__inner {
	position: relative;
	padding-top: 140px;
	padding-bottom: 88px;
	display: flex;
	flex-direction: column;
	gap: 18px;
}

.sc-hero__title {
	max-width: 820px;
}

/* The design's standfirst runs to 620px where the shared rule stops at 540px.
   Written as a descendant so the shared rule is untouched. */
.sc-hero .page-hero__lead {
	max-width: 620px;
}

/* -----------------------------------------------------------------------------
   2. The gallery card
   -----------------------------------------------------------------------------
   Lifted 40px over the hero's bottom edge, the same move the Progress page's
   stage panel makes. `z-index: 3` is the design's own figure and is what puts
   the card over the hero's glows.
   -------------------------------------------------------------------------- */
.sc-gallery-sec {
	position: relative;
	z-index: 3;
	margin-top: -40px;
	padding-bottom: 24px;
}

.sc-gallery {
	box-sizing: border-box;
	padding: clamp(16px, 3vw, 32px);
	border-radius: 28px;
	background: var(--surface);
	border: 1px solid var(--line);
	box-shadow: var(--lift-big);
	display: flex;
	flex-wrap: wrap;
	align-items: flex-start;
	gap: 28px 40px;
}

/* -----------------------------------------------------------------------------
   3. The tab list
   -----------------------------------------------------------------------------
   `role="tablist"` with `aria-orientation="vertical"`, and one shared panel
   whose content changes — which is how the design draws it (one
   `role="tabpanel"`, not one per tab).
   -------------------------------------------------------------------------- */
.sc-list-wrap {
	flex: 1 1 280px;
	min-width: 0;
	max-width: 340px;
	display: flex;
	flex-direction: column;
	gap: 10px;
}

.sc-list__head {
	padding: 0 6px;
	font-size: 13px;
	font-weight: 800;
	letter-spacing: 0.06em;
	text-transform: uppercase;
	color: var(--muted);
}

.sc-list {
	display: flex;
	flex-direction: column;
	gap: 6px;
	padding: 6px;
	border-radius: 20px;
	background: var(--bg);
}

/* The row's selected state is read off `aria-selected`, not off a second
   class. One source of truth: a row that LOOKS selected and does not say so to
   a screen reader is the defect that convention prevents, and it cannot happen
   when the attribute is what paints it. */
.sc-row {
	display: flex;
	align-items: center;
	gap: 12px;
	width: 100%;
	min-height: 60px;
	padding: 8px 12px 8px 8px;
	border-radius: 15px;
	border: 0;
	background: transparent;
	box-shadow: none;
	color: var(--ink);
	text-align: left;
	font-family: inherit;
	cursor: pointer;
	transition: background-color 0.25s ease-out, box-shadow 0.25s ease-out,
		transform 0.14s ease-out;
}
.sc-row[aria-selected="true"] {
	background: var(--surface);
	box-shadow: var(--lift);
}
/* The design's `hr-press`. Declared on this element rather than shipped as a
   class name, because `.hr-press` selects nothing in site.css — see the note
   above `.hw-hear` there. */
.sc-row:active {
	transform: scale(0.97);
}

.sc-row__tile {
	flex-shrink: 0;
	width: 40px;
	height: 40px;
	border-radius: 12px;
	background: var(--chip);
	color: var(--accent);
	display: flex;
	align-items: center;
	justify-content: center;
	transition: background-color 0.25s ease-out, color 0.25s ease-out;
}
.sc-row[aria-selected="true"] .sc-row__tile {
	background: var(--blue);
	color: #ffffff;
}

.sc-row__text {
	flex: 1;
	min-width: 0;
	display: flex;
	flex-direction: column;
	line-height: 1.25;
}
.sc-row__label {
	font-size: 16px;
	font-weight: 800;
}
.sc-who {
	font-size: 13px;
	color: var(--muted);
}

.sc-chev {
	flex-shrink: 0;
	opacity: 0.4;
}

/* -----------------------------------------------------------------------------
   4. The panel: the phone and the caption beside it
   -------------------------------------------------------------------------- */
/* NOTHING WRITES `hidden` ON THIS ELEMENT, and that is now true rather than
   merely intended — which is why there is no `.sc-panel[hidden]` rule here
   beside the ones on `.sc-cap` and `.sc-note`.

   It was not true for one commit. Every `.sc-row` tab carries
   `aria-controls="sc-panel"`, and scripts/site.js's generic tablist handler
   used to loop over every tab running `panel.hidden = !selected` against the
   element that id names. Several tabs, one panel: the last pass decided, so
   pressing any tab but the last left `hidden` set on the whole gallery
   panel, and `display: flex` below was the only reason it did not vanish.
   Measured in a real browser before the fix — `panel.hasAttribute('hidden')`
   true for tabs 0-5 and false for tab 6, while `getComputedStyle(panel)
   .display` stayed "flex" throughout.

   TWO DEFECTS WHOSE SYMPTOMS CANCELLED. The missing `[hidden]` override on
   `.sc-cap` and the wrong `hidden` write on `.sc-panel` hid each other: the
   override's absence kept the panel on screen despite the bad write, and the
   bad write was invisible because the override was absent. Adding
   `.sc-panel[hidden] { display: none }` on its own — the obvious-looking
   completion of this sheet's `[hidden]` rules — would have blanked the
   gallery on the first tab press. Fixed in the other order, in site.js: the
   generic handler now resolves panels as a set and stands down entirely on a
   tab list a page controller owns. See docs/coding.md. */
.sc-panel {
	flex: 999 1 560px;
	min-width: 0;
	display: flex;
	flex-wrap: wrap;
	align-items: flex-start;
	justify-content: center;
	gap: 28px 40px;
}

.sc-device {
	flex: 0 0 auto;
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 14px;
	max-width: 100%;
}

/* -----------------------------------------------------------------------------
   4.1 Day / Night
   -----------------------------------------------------------------------------
   THE ONE PLACE THIS PAGE DOES NOT MATCH ITS DRAWING, and it is a rule rather
   than a preference. Screens.dc.html draws these two buttons at
   `min-height: 40px` and the sliding indicator at `height: 40px`.
   docs/ui-rules.md sets a 44px floor for anything tappable, and says in terms
   that the scaled-mockup exemption covers "controls inside a depicted app
   screen" and NOT the site's own chrome. This control is the site's chrome: it
   sits outside the phone frame, at full scale, and a finger has to hit it. So
   both are built at 44px.

   Dylan has ruled the same way twice on this same defect class — "build the
   buttons at 44px" (Oct 28, 2026), covering EmuCrew's four sub-44px controls
   and the Progress page's four filter chips. This applies that decision; it
   does not make a new one. The design file itself is NOT edited to match:
   that half needs his words, and the director is asking him separately.
   -------------------------------------------------------------------------- */
.sc-mode {
	box-sizing: content-box; /* the design canvas's sizing: see site.css section 3 */
	position: relative;
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	gap: 4px;
	width: 220px;
	padding: 4px;
	border-radius: 14px;
	background: var(--chip);
}

/* The sliding indicator is a sibling, not a background on the checked button:
   it has to travel between the two, and a background cannot. `aria-hidden`
   because it says nothing a screen reader does not already get from
   `aria-checked`. 44px, raised from the design's 40px with the buttons above
   it, so the slider still covers the button it marks. */
.sc-mode__ind {
	position: absolute;
	top: 4px;
	left: 4px;
	width: calc((100% - 12px) / 2);
	height: 44px;
	border-radius: 11px;
	background: var(--surface);
	box-shadow: 0 2px 6px rgba(2, 17, 58, 0.16);
	transition: transform 0.32s cubic-bezier(0.3, 0.7, 0.3, 1);
}
.sc-mode[data-mode="day"] .sc-mode__ind {
	transform: translateX(0);
}
.sc-mode[data-mode="night"] .sc-mode__ind {
	transform: translateX(calc(100% + 4px));
}

.sc-mode__opt {
	position: relative;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: 6px;
	min-height: 44px;
	border: 0;
	border-radius: 11px;
	background: transparent;
	color: var(--ink);
	font-family: inherit;
	font-size: 14px;
	font-weight: 800;
	cursor: pointer;
}

/* -----------------------------------------------------------------------------
   4.2 The phone, and the line under it
   -----------------------------------------------------------------------------
   The frame itself is site.css's `.emu-frame` / `.emu-box` / `.emu-scale`,
   which the Home page already carries at exactly the sizes this design asks
   for: a 330x714 window with the 390x844 screen scaled to 0.846 inside it, and
   289x625 at 0.741 below 560px. The design calls the inner element
   `.emu-screen`; the site has called it `.emu-scale` since task R2a and that
   name is kept rather than a second one introduced.
   -------------------------------------------------------------------------- */
/* All but one note is `hidden` at any moment, the same as the captions.
   This rule does NOT set `display`, so the user agent's
   `[hidden] { display: none }` is unopposed and they really do disappear —
   measured, not assumed. The override below is written anyway, for the same
   reason .hw-says__note[hidden] is written in site.css: so that adding a
   `display` here later cannot quietly ship six stacked notes. */
.sc-note {
	font-size: 13px;
	font-weight: 700;
	color: var(--muted);
}
.sc-note[hidden] {
	display: none;
}

/* -----------------------------------------------------------------------------
   4.3 The caption column
   -------------------------------------------------------------------------- */
.sc-cap {
	flex: 1 1 260px;
	min-width: 0;
	max-width: 420px;
	display: flex;
	flex-direction: column;
	gap: 14px;
	padding-top: 58px;
}
/* `hidden` has to beat the `display: flex` above it, the same trap
   .tabpanel[hidden], .mobile-menu[hidden], .try__cap[hidden] and six more
   carry in site.css, and .emu[hidden] carries in mockups.css. An author
   `display` declaration outranks the user agent's `[hidden] { display: none }`
   whatever the source order, so without this rule every caption renders
   at once — all but one of them `hidden`, all of them on screen, stacked
   down the page.

   That is exactly what shipped. The markup, the attribute and
   scripts/screens.js were all correct throughout, which is why no test and no
   computed-style check saw it: `cap.hidden` was true and
   `getComputedStyle(cap).display` was "flex". Only the rendered page was
   wrong. src/html/hidden-display.test.ts is the guard that now closes it. */
.sc-cap[hidden] {
	display: none;
}

.sc-cap__who {
	font-size: 13px;
	font-weight: 800;
	letter-spacing: 0.06em;
	text-transform: uppercase;
	color: var(--accent);
}

.sc-cap__points {
	margin: 0;
	padding: 0;
	list-style: none;
	display: flex;
	flex-direction: column;
	gap: 10px;
}

.sc-point {
	display: flex;
	gap: 12px;
	align-items: flex-start;
	padding: 14px 16px;
	border-radius: 16px;
	background: var(--bg);
	font-size: 16px;
	line-height: 1.5;
}

.sc-point__tick {
	flex-shrink: 0;
	width: 24px;
	height: 24px;
	margin-top: 1px;
	border-radius: 12px;
	background: var(--chip);
	color: var(--accent);
	display: flex;
	align-items: center;
	justify-content: center;
}

/* Not a control — a label. The 44px floor is about things a finger has to
   hit, and nothing happens when this is pressed. */
.sc-cap__live {
	align-self: flex-start;
	display: inline-flex;
	align-items: center;
	gap: 8px;
	min-height: 34px;
	padding: 0 12px;
	border-radius: 17px;
	background: var(--chip);
	color: var(--accent);
	font-size: 13px;
	font-weight: 800;
}

/* -----------------------------------------------------------------------------
   5. On to the next page
   -----------------------------------------------------------------------------
   `:hover` IS LISTED BESIDE THE BASE STATE, and that is load-bearing rather
   than tidy. Section 3 of site.css carries `a:hover { color: #0442b0 }`, a
   type selector plus a pseudo-class, which outranks a single class — so with
   only the base selector here the card's title would turn brand blue on
   hover while the "Next" label beside it, which declares `var(--muted)` of
   its own, would not move. That exact defect shipped on the Progress page for
   one commit, and the CSSOM sweep cannot see it: `Element.matches()` answers
   for an element's CURRENT state, so no `:hover` rule ever matches an element
   nobody is hovering (docs/coding.md, Oct 28, 2026).
   -------------------------------------------------------------------------- */
.sc-onward-sec {
	padding-top: 56px;
	padding-bottom: 96px;
}

.sc-onward,
.sc-onward:hover {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 16px;
	padding: 22px 24px;
	border-radius: 22px;
	background: var(--surface);
	border: 1px solid var(--line);
	box-shadow: var(--lift-big);
	color: var(--ink);
	text-decoration: none;
}

.sc-onward {
	transition: transform 0.14s ease-out, box-shadow 0.2s ease-out,
		background-color 0.2s ease-out;
}
.sc-onward:active {
	transform: scale(0.97);
}

.sc-onward__text {
	display: flex;
	flex-direction: column;
	gap: 4px;
}

.sc-onward__label {
	font-size: 13px;
	font-weight: 800;
	letter-spacing: 0.06em;
	text-transform: uppercase;
	color: var(--muted);
}

.sc-onward__title {
	font-size: clamp(22px, 2.6vw, 28px);
	font-weight: 800;
}

.sc-onward__arrow {
	flex-shrink: 0;
	width: 48px;
	height: 48px;
	border-radius: 24px;
	background: var(--blue);
	color: #ffffff;
	display: flex;
	align-items: center;
	justify-content: center;
	box-shadow: 0 10px 24px rgba(4, 97, 248, 0.38);
}

/* -----------------------------------------------------------------------------
   6. The caption's entrance
   -----------------------------------------------------------------------------
   The design remounts its caption on every tab change, which replays the
   entrance. A real DOM does not remount, so the same A/B alternation the
   Progress log and the Home "Try the app" caption use is reproduced here:
   two classes with the same timing and two keyframes with the same frames,
   swapped on each change so the animation restarts. `hrSwap` and `hrSwapB`
   are declared in site.css and already applied there, so nothing here orphans
   a keyframe.

   The hidden first frame lives inside the keyframes, not in these rules, so
   section 25's reduced-motion backstop leaves the caption and the phone at
   their natural, visible positions rather than at `opacity: 0`.
   -------------------------------------------------------------------------- */
.sc-swap--a {
	animation: hrSwap 0.45s cubic-bezier(0.2, 0.8, 0.2, 1) both;
}
.sc-swap--b {
	animation: hrSwapB 0.45s cubic-bezier(0.2, 0.8, 0.2, 1) both;
}

/* -----------------------------------------------------------------------------
   7. Narrow widths
   -----------------------------------------------------------------------------
   The design's own three breakpoints for this page, and nothing invented.
   -------------------------------------------------------------------------- */

/* The tab list stops being a column beside the phone and becomes a full-width
   two-column grid above it. */
@media (max-width: 1000px) {
	.sc-list-wrap {
		max-width: none;
		flex-basis: 100%;
	}
	.sc-list {
		display: grid;
		grid-template-columns: repeat(2, minmax(0, 1fr));
	}
}

/* The caption's 58px top padding exists to line its eyebrow up with the top of
   the phone. Once it is below the phone rather than beside it, it is padding
   above nothing. */
@media (max-width: 760px) {
	.sc-cap {
		padding-top: 0;
	}
}

/* At the narrowest widths the row drops its "who it is for" line and its
   chevron and shortens, so every row still fits without the grid scrolling.
   52px is still past the 44px floor. */
@media (max-width: 480px) {
	.sc-who,
	.sc-chev {
		display: none;
	}
	.sc-row {
		min-height: 52px;
	}
}
