/*
 * Alia Design System v1 — shared stylesheet.
 * Spec of record: docs/design-system.md
 * First reference implementation: web/pages/aiam-partnership.html
 *
 * Loaded after app.css so .ds-* wins ties; tokens are at :root so any
 * page can consume them.
 *
 * Opt-in: Global element selectors (body, h1-h3, p) are scoped to
 * .ds-page. Pages opt in by adding class="ds-page" to a wrapper div
 * (or to the body element). Non-ds pages keep their existing app.css
 * styling untouched. The :root tokens below remain site-wide so any
 * page can reference --color-primary, --font-body, etc.
 */

/* -----------------------------------------------------------------------
 * 1b. Site-wide nav + accessibility repairs (2026-07-24, Fable round 4)
 *
 * These apply to EVERY page (not .ds-page-scoped): they fix the top bar
 * and the skip link the a11y pass introduced without styles.
 * --------------------------------------------------------------------- */

/* Skip link: standard visually-hidden-until-keyboard-focus treatment.
   Sighted mouse users never see it; Tab reveals it as the first stop. */
.ds-skip-link {
	position: absolute;
	left: -9999px;
	top: 0;
	z-index: 1001;
	background: #154177;
	color: #fff;
	font-family: inherit;
	font-size: 15px;
	font-weight: 600;
	text-decoration: none;
	padding: 12px 20px;
	border-radius: 0 0 8px 0;
}
.ds-skip-link:focus {
	position: fixed;
	left: 0;
	top: 0;
	color: #fff;
	outline: 2px solid #fff;
	outline-offset: -5px;
}

/* -----------------------------------------------------------------------
 * Warm-neutral migration (2026-08-21).
 *
 * Vision critique of /stna-classes-in-columbus-ohio and /cincinnati named the
 * same thing at agreement 2: section bands render as COOL neutral gray
 * (#f2f2f2 / #f1f1f1, Foundation-era defaults in app.css .panel and .card)
 * while the design system specifies WARM neutrals (--color-surface-alt
 * #f2efe9). The cool cast is why "the brand never actually shows up" on those
 * pages. This remap is the design system's own line -- "--color-bg #faf9f7
 * replaces #F0F0F0 sections" -- extended to the two legacy classes that paint
 * most of those bands. Loads after app.css so no !important is needed.
 *
 * NOTE: admin/account pages share this stylesheet; their panels warm-shift
 * from gray to cream too, which is a tint change, not a layout change.
 * --------------------------------------------------------------------- */
.panel,
.card {
	background-color: var(--color-surface-alt);
}

/* De-greening the last Foundation CTAs (2026-08-21). The nav pill was done in
   template.html; these are the IN-CONTENT "Register" anchors still wearing
   Foundation green (#43AC6A, white text ~2.2:1). Design system §1: green is
   off-brand, primary CTAs go orange -- here the ds-btn--cta pair
   (--color-accent-deep / hover #9a4506), 4.8:1 with white.
   Anchors only: form <button>/<input> submits keep their semantics. */
a.button.success {
	background-color: var(--color-accent-deep);
	color: #fff;
}
a.button.success:hover,
a.button.success:focus {
	background-color: #9a4506;
	color: #fff;
}

/* Top bar: solid brand blue on every page — overrides home.html's
   transparent-nav treatment (white logo/links were invisible before the
   hero loaded, and permanently once the left nav wrapped). Auto height so
   nav items can never fall out of the painted bar. */
#navbar.top-bar {
	background: #154177;
	height: auto;
	min-height: 5rem;
	overflow: visible;
}
/* Foundation's `.title-area` is the top row of the top-bar (logo, login,
   register, hamburger). It defaults to a white background which makes the
   bar look "chunky" (white-on-top, blue-on-bottom). Unify the bar by
   painting the title-area blue too, and make the text/icons in it white
   so they stay readable. */
#navbar .title-area,
#navbar .title-area .name a,
#navbar .title-area .alia-logo img {
	background: #154177;
	color: #fff;
}
#navbar .title-area a { color: #fff; }
/* Mobile wordmark. The small-only slot used to hold a generic house glyph, so
   phones opened with no brand mark anywhere. Cap the height so the wordmark
   sits in the bar without pushing it taller than the medium-up version. */
#navbar .title-area .alia-logo--small img {
	max-height: 34px;
	width: auto;
	display: block;
}
/* On a 320px screen the wordmark measures 156px, and 156 + Register (92) +
   menu (70) = 318px, so the bar tipped into a second row with 2px to spare.
   Everything else in the bar is either the primary CTA or the way into the
   menu, so the wordmark is the only thing that can give — and shrinking it
   is much better than dropping the brand mark or the Register button. */
@media only screen and (max-width: 22.5em) {
	#navbar .title-area .alia-logo--small img { max-height: 26px; }
}
/* Register Now should be 3px larger than "My Account" (which inherits
   1em = 16px from .ds-page). 1.1875em = 19px. The 700 weight + 19px
   gives the CTA the right visual weight against the lighter nav
   items without making it heavy enough to look like a different
   brand. Foundation's default top-bar .button font-size is 1.25rem
   (20px); this override brings it back to 3px-above-body to match
   the user's "bigger than My Account, but not huge" ask. */
#navbar .title-area .register-button,
#navbar .top-bar-section .register-button {
	font-size: 1.1875em;
	font-weight: 700;
}
#navbar #simple-menu,
#navbar .title-area .fa-bars { color: #fff; }

/* -----------------------------------------------------------------------
   Webfonts
   --------------------------------------------------------------------- */
/* Rockwell is declared in app.css (the only face it has). Libre Franklin is
   declared here because design-system.css is the only stylesheet that loads
   after app.min.css, and the campus hero checklist is styled by the inline
   block in template.html. Self-hosted like Rockwell - no third-party request
   on a page a student is looking at while deciding whether to enrol.

   Libre Franklin is a VARIABLE font (one file covers 100-900), so there is a
   single @font-face per subset rather than one per weight. Subset files and
   the SIL Open Font License are in web/fonts/LibreFranklin/. */
@font-face {
	font-family: "Libre Franklin";
	src: url(/fonts/LibreFranklin/LibreFranklin-latin.woff2) format("woff2");
	font-weight: 100 900;
	font-style: normal;
	font-display: swap;
	unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
	font-family: "Libre Franklin";
	src: url(/fonts/LibreFranklin/LibreFranklin-latin-ext.woff2) format("woff2");
	font-weight: 100 900;
	font-style: normal;
	font-display: swap;
	unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C4, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

/* Dynamic header height (2026-07-31). The `<script>` in template.html
   measures #navbar.offsetHeight on load and resize, then writes it to
   `--header-height` on :root. Use this var in `calc()` to fill exactly
   the remaining viewport (or any container) below the bar. The
   `.nav-spacer` is also kept in sync for any legacy inline-positioned
   content that depends on it. */
:root {
	--header-height: 80px;
}
@media (max-width: 640px) {
	:root { --header-height: 110px; }
}

/* Dynamic vertical centering. Fill the remaining viewport below the
   header and center the content vertically. Works on web, mobile, and
   when the page only takes up part of the screen (the form is centered
   instead of stuck at the top). Uses `--header-height` from the script
   above so it adapts to whatever the actual bar height is. */
.ds-fill-viewport {
	min-height: calc(100vh - var(--header-height));
	display: flex;
	align-items: center;
	box-sizing: border-box;
}
.ds-fill-viewport > * { width: 100%; }
/* Three left-nav items barely overflow Foundation's default link padding
   at laptop widths, wrapping out of the bar. Tighten to fit one row. */
#navbar .top-bar-section ul.left li > a {
	padding: 0 12px;
	font-size: 1em;
}

/* -----------------------------------------------------------------------
 * 2. Design tokens (re-rooted from .aiam-page to :root)
 * --------------------------------------------------------------------- */
:root {
	--color-primary: #154177;
	--color-primary-deep: #0d2c52;
	--color-primary-tint: #e8eef6;
	/* ORANGE TIERS. WCAG thresholds differ by size and by whether the thing is
	   text at all, so one orange for everything means the whole brand gets
	   darkened to satisfy the strictest case. Pick by CONTEXT, worst-case
	   surface first. Ratios below are the WORST across every surface in this
	   file (#fff, --color-bg #faf9f7, --color-surface-alt #f2efe9, .g-bk
	   #f0f0f0) -- --color-bg alone is NOT the worst case, the alt surfaces are.

	   Large text (>=24px, or >=18.7px bold) needs 3:1. Normal text needs 4.5:1.
	   Non-text decoration -- rules, bars, shapes -- has NO requirement. */

	/* Display: h1 and other large headings on light surfaces. 3.21:1 worst
	   case. The most vivid orange that clears 3:1 on EVERY surface here.
	   #eb6b0b measures 3.01:1 on --color-bg and looks tempting, but drops to
	   2.76:1 on --color-surface-alt and fails. Do not "fix" this by darkening
	   it back to --color-accent-deep: that is a normal-text value being
	   applied to large text, which is what made the brand look muddy. */
	--color-accent: #d9620a;

	/* 2.98:1 worst case -- fails large text by a hair. Non-text decoration
	   only (rules, bars, fills). Never set type in this. */
	--color-accent-bright: #f0681a;

	/* Normal-size text and CTAs on light surfaces. 4.25:1 worst case. */
	--color-accent-deep: #b85408;

	/* Brand-match orange, sampled from web/images/alia-white.png swoosh
	   (509/535 opaque warm px are exactly #f57b20). Fails contrast on light
	   backgrounds (2.58:1 on --color-bg), so only use it on --color-primary
	   or darker (3.77:1, AA large text) -- or as non-text decoration, where
	   no ratio applies and the true brand colour belongs. */
	--color-logo-orange: #f57b20;
	/* The brand orange, stepped light enough to be SMALL text on a dark ground.
	   --color-logo-orange is 3.77:1 on --color-primary, which the note above
	   calls out as AA-large-text only. A .ds-eyebrow is 14px bold tracked caps,
	   which is not large text, so on a dark hero it needs this instead: the same
	   hue, carried to 4.79:1 on --color-primary and 6.57:1 on
	   --color-primary-deep. A peach (#fcdcb8) was used on the calendar hero
	   before this existed, which reads as cream rather than as the Alia
	   orange. The calendar hero is currently the only dark hero on the site;
	   every other hero is light and uses --color-accent-deep. */
	--color-brand-on-dark: #f79c57;	/* Warm cream surface tint in the accent/orange family. Surface fills only
	   (the job-placement card); pair with --color-primary text, never orange
	   text -- orange on this cream fails normal-text contrast. */
	--color-accent-tint: #fdf1e0;
	--color-bg: #faf9f7;
	--color-surface: #ffffff;
	--color-surface-alt: #f2efe9;
	--color-border: #ddd8d0;
	--color-text: #2b2723;
	--color-muted: #6b6560;
	--color-success: #2e7d4f;
	--color-warning: #b7791f;
	--color-danger: #a33c3c;
	--font-heading: "rockwell", "Rockwell", Georgia, serif;
	--font-body: "rockwell", "Rockwell", "Georgia", serif;
	/* 2026-10-23: the campus hero checklist (campus-hero-blurbs) moved to
	   Libre Franklin - the owner picked it from the six-option render in
	   docs/type-options-campus-blurbs.html. Everything else stays Rockwell;
	   this is the only component that consumes --font-blurb. */
	--font-blurb: "Libre Franklin", Helvetica, Arial, sans-serif;
	--space-1: 4px;
	--space-2: 8px;
	--space-3: 12px;
	--space-4: 16px;
	--space-6: 24px;
	--space-8: 32px;
	--space-12: 48px;
	--space-16: 64px;
	--space-24: 96px;
	--space-32: 128px;
}

/* -----------------------------------------------------------------------
 * 3. Global type + body defaults (opt-in via .ds-page; see header)
 * --------------------------------------------------------------------- */
.ds-page {
	font-family: var(--font-body);
	color: var(--color-text);
	background: var(--color-bg);
	font-size: 16px;
	line-height: 1.6;
}

.ds-page h1,
.ds-page h2,
.ds-page h3 {
	font-family: var(--font-heading);
	color: var(--color-primary);
	line-height: 1.2;
	margin: 0 0 16px;
}
.ds-page h1 { font-size: 32px; line-height: 1.15; }
.ds-page h2 { font-size: 26px; }
.ds-page h3 { font-size: 21px; line-height: 1.3; }

.ds-page p {
	font-size: 1em;
	font-weight: 400;
	color: var(--color-text);
	max-width: 72ch;
}

/* -----------------------------------------------------------------------
 * 4. Components (formerly scoped to .aiam-page, now unscoped)
 * --------------------------------------------------------------------- */
.ds-container {
	max-width: 1200px;
	margin: 0 auto;
	padding: 0 16px;
}

.ds-eyebrow {
	display: block;
	/* 2026-08-22 readability pass (owner: small tracked caps hurt to read):
	   13->14px, tracking relaxed, weight up so letterforms stay crisp. */
	font-size: 14px;
	font-weight: 700;
	letter-spacing: 0.05em;
	text-transform: uppercase;
	color: var(--color-accent-deep);
	margin-bottom: 12px;
}

.ds-badge {
	display: inline-block;
	font-size: 13px;
	font-weight: 600;
	padding: 4px 10px;
	border-radius: 999px;
	background: #fdf0e5;
	color: var(--color-accent-deep);
	margin-bottom: 16px;
}
/* 2026-08-21: both campuses wore the same peach badge, so Columbus and
   Cincinnati rows were indistinguishable at a glance. Columbus keeps the
   navy of the brand; Cincinnati takes the orange. White on --color-primary
   is 8.6:1; white on --color-accent-deep is 5.5:1 -- both AA. */
.ds-badge--columbus { background: var(--color-primary); color: #fff; }
.ds-badge--cincinnati { background: var(--color-accent-deep); color: #fff; }

/* Buttons */
.ds-btn {
	display: inline-block;
	font-family: var(--font-body);
	font-size: 16px;
	font-weight: 600;
	padding: 14px 32px;
	border-radius: 8px;
	text-decoration: none;
	transition: background-color 150ms ease, color 150ms ease;
	min-height: 44px;
}
.ds-btn:focus {
	outline: 2px solid var(--color-primary);
	outline-offset: 2px;
}
.ds-btn--cta { background: var(--color-accent-deep); color: #fff; }
.ds-btn--cta:hover { background: #9a4506; color: #fff; }
.ds-btn--primary { background: var(--color-primary); color: #fff; }
.ds-btn--primary:hover { background: var(--color-primary-deep); color: #fff; }
.ds-btn--ghost { background: transparent; color: var(--color-primary); }
.ds-btn--ghost:hover { background: var(--color-primary-tint); color: var(--color-primary); text-decoration: underline; }


/* Hero */
.ds-hero {
	background: linear-gradient(180deg, var(--color-primary-tint) 0%, var(--color-bg) 100%);
	padding: 48px 0 64px;
}
.ds-hero .ds-container {
	display: flex;
	flex-direction: column;
	gap: 32px;
	align-items: center;
}
.ds-hero-copy { max-width: 560px; }
.ds-hero-copy .ds-sub {
	font-size: 18px;
	max-width: 60ch;
	margin-bottom: 24px;
}
.ds-hero-art { width: 100%; max-width: 560px; }
.ds-hero-art img { width: 100%; height: auto; border-radius: 12px; }
.ds-hero-actions { display: flex; flex-wrap: wrap; gap: 12px; align-items: center; }
/* 2026-10-23: the partnership hero lost its artwork - the image element pointed
   at an SVG that was invalid XML (a double hyphen inside an XML comment), so
   every browser rejected it and showed a broken-image placeholder. The copy now
   spans the full container instead of sitting in a 560px column. The paragraph
   keeps its own 60ch measure, so the line length stays readable; only the
   badge, heading and buttons go wide. */
.ds-hero--wide .ds-hero-copy { max-width: none; }
.ds-hero--wide .ds-container { justify-content: flex-start; }

/* Callout banner */
.ds-callout {
	background: var(--color-primary);
	color: #fff;
	padding: 24px 0;
}
.ds-callout p { color: #fff; margin: 0; max-width: none; }
.ds-callout a { color: #fff; text-decoration: underline; font-weight: 600; }
.ds-callout .ds-container { text-align: center; }

/* Sections */
.ds-section { padding: 48px 0; }
.ds-section--alt { background: var(--color-surface-alt); }
.ds-section-head { text-align: center; max-width: 640px; margin: 0 auto 32px; }
.ds-section-head p { margin: 0 auto; }

/* Cards */
.ds-card-grid {
	display: grid;
	grid-template-columns: 1fr;
	gap: 24px;
}
.ds-card {
	background: var(--color-surface);
	border: 1px solid var(--color-border);
	border-radius: 12px;
	padding: 24px;
	box-shadow: 0 1px 3px rgba(43,39,35,.08);
}
a.ds-card {
	display: block;
	text-decoration: none;
	color: var(--color-text);
	transition: box-shadow 150ms ease, transform 150ms ease;
}
a.ds-card:hover {
	box-shadow: 0 4px 12px rgba(43,39,35,.12);
	transform: translateY(-2px);
}
a.ds-card:focus {
	outline: 2px solid var(--color-primary);
	outline-offset: 2px;
}
.ds-card-icon {
	width: 48px;
	height: 48px;
	border-radius: 50%;
	background: var(--color-primary-tint);
	color: var(--color-primary);
	font-size: 22px;
	line-height: 48px;
	text-align: center;
	margin-bottom: 16px;
}
.ds-card h3 { margin-bottom: 8px; }
.ds-card p { margin: 0; font-size: 15px; }
.ds-card .ds-card-link {
	display: inline-block;
	margin-top: 12px;
	font-weight: 600;
	color: var(--color-primary);
}

/* Why section + partner slots */
.ds-why {
	display: flex;
	flex-direction: column;
	gap: 32px;
}
.ds-why-copy p { margin-bottom: 16px; }
.ds-partner-panel {
	display: flex;
	flex-direction: column;
	gap: 16px;
	align-items: center;
}
.ds-partner-logo {
	width: 128px;
	background: var(--color-surface);
	border: 1px solid var(--color-border);
	border-radius: 12px;
	padding: 16px;
}
.ds-partner-logo img { width: 100%; height: auto; display: block; }
.ds-partner-media { width: 100%; }
.ds-partner-media img {
	width: 100%;
	height: auto;
	aspect-ratio: 16 / 9;
	object-fit: cover;
	border-radius: 12px;
	display: block;
}
.ds-partner-caption {
	font-size: 14px;
	color: var(--color-muted);
	text-align: center;
	margin: 0;
}

/* CTA section */
.ds-cta-section {
	background: var(--color-primary-deep);
	color: #fff;
	text-align: center;
	padding: 64px 0;
}
.ds-cta-section h2 { color: #fff; }
.ds-cta-section p { color: var(--color-primary-tint); margin: 0 auto 24px; }

/* Contact strip */
.ds-contact { text-align: center; }
.ds-contact p { margin: 0 auto 8px; }
.ds-contact a { color: var(--color-primary); font-weight: 600; }

/* -----------------------------------------------------------------------
 * 5. Breakpoints (mobile-first, min-width; see design-system.md §4)
 * --------------------------------------------------------------------- */
@media only screen and (min-width: 768px) {
	.ds-page { font-size: 17px; }
	.ds-page h1 { font-size: 40px; }
	.ds-page h2 { font-size: 32px; }
	.ds-page h3 { font-size: 24px; }
	.ds-section { padding: 64px 0; }
	.ds-card-grid { grid-template-columns: 1fr 1fr; }
	.ds-hero { padding: 64px 0 80px; }
	.ds-hero .ds-container { flex-direction: row; justify-content: space-between; }
	.ds-partner-panel { flex-direction: row; align-items: flex-start; }
	.ds-partner-logo { flex: 0 0 160px; width: 160px; }
}
@media only screen and (min-width: 1024px) {
	.ds-card-grid { grid-template-columns: repeat(4, 1fr); }
	.ds-card-grid--programs { grid-template-columns: repeat(4, 1fr); }
	.ds-why { flex-direction: row; }
	.ds-why-copy { flex: 1 1 55%; }
	.ds-why-partner { flex: 1 1 45%; }
	.ds-partner-panel { flex-direction: column; align-items: center; }
}

/* -----------------------------------------------------------------------
 * 6. Calendar component (.ds-calendar; see design-system.md and
 *    KNOWN_ISSUES.md [FEATURE] School calendar view)
 * --------------------------------------------------------------------- */
.ds-cal-filters {
	display: flex;
	flex-wrap: wrap;
	gap: 12px;
	align-items: center;
	justify-content: center;
	margin-bottom: 32px;
}
/* Pill tabs: the calendar's campus filter moved to the #ds-cal-campus-gate
   select (2026-08-21), but this remains a shared component -- blog.html uses
   .ds-tab for its topic-filter rail -- so the styles stay. */
.ds-tabs {
	display: inline-flex;
	background: var(--color-surface);
	border: 1px solid var(--color-border);
	border-radius: 999px;
	padding: 4px;
	gap: 4px;
}
.ds-tab {
	border: 0;
	background: transparent;
	font-family: var(--font-body);
	font-size: 15px;
	font-weight: 600;
	color: var(--color-primary);
	padding: 10px 20px;
	min-height: 44px;
	border-radius: 999px;
	cursor: pointer;
	transition: background-color 150ms ease, color 150ms ease;
}
.ds-tab:hover { background: var(--color-primary-tint); }
.ds-tab:focus { outline: 2px solid var(--color-primary); outline-offset: 2px; }
.ds-tab.is-active { background: var(--color-primary); color: #fff; }

/* Campus gate (2026-08-21): replaced the All/Columbus/Cincinnati pill tabs.
   This select is the page's primary control -- subtitle-sized, bold, first
   in the toolbar -- and it is a HARD gate: one campus at a time. */.ds-cal-campus-label {
	display: flex;
	flex-direction: column;
	gap: 4px;
}
.ds-cal-campus-name {
	font-family: var(--font-body);
	font-size: 14px;
	font-weight: 700;
	letter-spacing: .06em;
	text-transform: uppercase;
	color: var(--color-muted);
}
#ds-cal-campus-gate {
	font-family: var(--font-body);
	font-size: 1.15rem;
	font-weight: 700;
	color: var(--color-primary);
	background-color: var(--color-surface);
	/* app.min.css strips the native select caret (appearance:none) without
	   drawing its own -- draw one, or the gate reads as a static button. */
	appearance: none;
	-webkit-appearance: none;
	background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='9' viewBox='0 0 14 9'%3E%3Cpath d='M1 1l6 6 6-6' fill='none' stroke='%23154177' stroke-width='2.5' stroke-linecap='round'/%3E%3C/svg%3E");
	background-repeat: no-repeat;
	background-position: right 16px center;
	border: 2px solid var(--color-primary);
	border-radius: 10px;
	padding: 10px 44px 10px 16px;
	min-height: 48px;
	cursor: pointer;
}
#ds-cal-campus-gate:focus { outline: 2px solid var(--color-logo-orange); outline-offset: 2px; }

/* Month pager (2026-08-21): arrows step the visible month window one month
   per click; the range label between them names what is on screen.
   Background/colour carry !important because app.min.css styles bare buttons
   (Foundation teal #008cba) at equal-or-higher specificity -- measured live,
   the disabled prev arrow was rendering in that teal. */
.ds-cal-nav {
	display: flex;
	align-items: center;
	justify-content: center;
	gap: 18px;
	margin-bottom: 22px;
}
.ds-cal-nav-btn {
	width: 44px;
	height: 44px;
	border-radius: 999px;
	border: 1px solid var(--color-border);
	background-color: var(--color-surface) !important;
	color: var(--color-primary) !important;
	font-size: 22px;
	line-height: 1;
	cursor: pointer;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	transition: background-color 150ms ease, border-color 150ms ease;
}
.ds-cal-nav-btn:hover:not(:disabled) { background-color: var(--color-primary-tint) !important; border-color: var(--color-primary); }
.ds-cal-nav-btn:focus { outline: 2px solid var(--color-primary); outline-offset: 2px; }
/* Disabled = quiet grey, not a filled pale tint: filled-but-faded read as an
   active state and made prev/next look inverted. */
.ds-cal-nav-btn:disabled {
	background-color: transparent !important;
	color: var(--color-muted) !important;
	border-color: var(--color-border);
	opacity: .55;
	cursor: default;
}
.ds-cal-range {
	font-family: rockwell,Helvetica;
	font-weight: 700;
	color: var(--color-primary);
	font-size: 16px;
	/* flex + min-width:0, not a fixed 240px floor: at 390px the two 44px
	   arrows plus a rigid label overflowed the viewport by ~9px. */
	flex: 1 1 auto;
	min-width: 0;
	text-align: center;
}
.ds-cal-program {
	font-family: var(--font-body);
	font-size: 15px;
	color: var(--color-text);
	background-color: var(--color-surface);
	/* Same Foundation appearance:none bleed as the campus gate: without a
	   drawn caret these read as static text inputs. */
	appearance: none;
	-webkit-appearance: none;
	background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 14 9'%3E%3Cpath d='M1 1l6 6 6-6' fill='none' stroke='%232b2723' stroke-width='2' stroke-linecap='round'/%3E%3C/svg%3E");
	background-repeat: no-repeat;
	background-position: right 12px center;
	border: 1px solid var(--color-border);
	border-radius: 8px;
	padding: 10px 34px 10px 14px;
	min-height: 44px;
}
.ds-cal-program:focus { outline: 2px solid var(--color-primary); outline-offset: 2px; }
.ds-calendar {
	display: grid;
	grid-template-columns: 1fr;
	gap: 24px;
}
.ds-cal-month {
	background: var(--color-surface);
	border: 1px solid var(--color-border);
	border-radius: 12px;
	padding: 24px;
	box-shadow: 0 1px 3px rgba(43,39,35,.08);
}
.ds-cal-month > h3 {
	margin-bottom: 16px;
	padding-bottom: 12px;
	border-bottom: 2px solid var(--color-primary-tint);
}
.ds-cal-row {
	width: 100%;
	text-align: left;
	border: 0;
	background: transparent;
	font-family: var(--font-body);
	font-size: 15px;
	color: var(--color-text);
	padding: 12px 8px;
	min-height: 44px;
	border-radius: 8px;
	cursor: pointer;
	display: flex;
	align-items: baseline;
	gap: 10px;
	transition: background-color 150ms ease;
}
.ds-cal-row:hover { background: var(--color-primary-tint); }
.ds-cal-row:focus { outline: 2px solid var(--color-primary); outline-offset: 2px; }
.ds-cal-row .ds-cal-date {
	font-weight: 700;
	color: var(--color-primary);
	white-space: nowrap;
}
.ds-cal-row .ds-cal-prog { flex: 1 1 auto; }
.ds-cal-row .ds-badge { margin-bottom: 0; }
.ds-cal-row .fa { color: var(--color-muted); transition: transform 150ms ease; }
.ds-cal-row[aria-expanded="true"] .fa { transform: rotate(90deg); }
.ds-cal-detail {
	display: none;
	margin: 0 8px 12px;
	padding: 16px;
	background: var(--color-bg);
	border-radius: 8px;
	font-size: 15px;
}
.ds-cal-detail.is-open { display: block; }
.ds-cal-detail p { margin: 0 0 8px; }
.ds-cal-detail .ds-btn { padding: 10px 20px; font-size: 15px; margin-top: 8px; }
.ds-cal-empty {
	color: var(--color-muted);
	font-size: 15px;
	padding: 12px 8px;
}
.ds-cal-empty a { color: var(--color-primary); font-weight: 600; }

/* ---------------------------------------------------------------------
 * v2 of the empty state: inline "get notified" form. FABLE_HANDOFF task
 * `calendar-interest-list` — see also KNOWN_ISSUES.md [FEATURE] School
 * calendar view. v1 was a single-line "Contact us" link; v2 is a real
 * form so prospects can opt in without leaving the page. Backend lives
 * at web/api/interest_list.php (POST, JSON). Fable may redesign later;
 * the structure is intentionally minimal so it's easy to restyle.
 * --------------------------------------------------------------------- */
.ds-cal-empty-form {
	padding: 12px 8px 16px;
	font-size: 15px;
	color: var(--color-text);
}
.ds-cal-empty-form p { margin: 0 0 10px; color: var(--color-muted); }
.ds-cal-empty-form .ds-interest-grid {
	display: grid;
	grid-template-columns: 1fr;
	gap: 10px;
	align-items: end;
	margin-bottom: 12px;
}
.ds-cal-empty-form label.ds-interest-field {
	display: flex;
	flex-direction: column;
	font-size: 14px;
	color: var(--color-muted);
	gap: 4px;
}
.ds-cal-empty-form label.ds-interest-field input,
.ds-cal-empty-form label.ds-interest-field select {
	font-family: var(--font-body);
	font-size: 15px;
	padding: 8px 10px;
	border: 1px solid var(--color-border);
	border-radius: 6px;
	background: var(--color-surface);
	color: var(--color-text);
	min-height: 40px;
}
.ds-cal-empty-form label.ds-interest-field input:focus,
.ds-cal-empty-form label.ds-interest-field select:focus {
	outline: 2px solid var(--color-primary);
	outline-offset: 1px;
}
.ds-cal-empty-form .ds-interest-submit {
	display: flex;
	flex-wrap: wrap;
	gap: 10px;
	align-items: center;
	margin-top: 8px;
}
.ds-cal-empty-form .ds-interest-submit .g-recaptcha { transform: scale(0.85); transform-origin: 0 0; }
.ds-cal-empty-form .ds-interest-msg {
	margin-top: 8px;
	font-size: 14px;
	min-height: 1.4em;
}
.ds-cal-empty-form .ds-interest-msg.is-success { color: var(--color-success); }
.ds-cal-empty-form .ds-interest-msg.is-error   { color: var(--color-danger); }
@media only screen and (min-width: 640px) {
	.ds-cal-empty-form .ds-interest-grid {
		grid-template-columns: 1.4fr 1fr 1fr auto;
	}
	.ds-cal-empty-form .ds-interest-submit { flex-wrap: nowrap; }
}
@media only screen and (min-width: 768px) {
	.ds-calendar { grid-template-columns: 1fr 1fr; }
	/* 2026-08-21: space-between on four mismatched children put the cohort
	   select on a second row at far left while tabs/status/selects sat at
	   three different heights. A grid pins tabs + the two labelled selects to
	   one baseline row and gives the live status line its own centred row. */
	.ds-cal-filters {
		display: grid;
		grid-template-columns: auto auto auto;
		justify-content: space-between;
		align-items: end;
	}
	.ds-cal-status {
		grid-row: 2;
		grid-column: 1 / -1;
		justify-self: center;
		margin-top: 10px;
	}
}
@media only screen and (min-width: 1024px) {
	.ds-calendar { grid-template-columns: repeat(3, 1fr); }
}

/* ---------------------------------------------------------------------
 * 6b. Depth pass (2026-08-21, owner: "you're flattening the look of it").
 * Synthesised from three parallel critique lenses (elevation / motion /
 * light planes). One shadow language throughout: warm ink pairs -- a tight
 * key plus a wide ambient -- with a navy-chromed pair reserved for the
 * navy-bordered campus gate so the toolbar parses gate-first by height.
 * Appended after the zebra/hairline rules ON PURPOSE: :hover needs to win
 * the source-order tie against .ds-cal-row:nth-of-type(even), which was
 * eating the hover tint on even rows.
 * --------------------------------------------------------------------- */
:root {
	--elev-1: 0 1px 2px rgba(43,39,35,.05), 0 3px 8px -2px rgba(43,39,35,.07);
	--elev-2: 0 2px 4px rgba(43,39,35,.06), 0 8px 20px -6px rgba(43,39,35,.12);
	--elev-navy: 0 1px 2px rgba(13,44,82,.18), 0 6px 16px -6px rgba(13,44,82,.28);
}
/* Cards: paper resting on the warm ground; navy-shaded hairline edge. */
.ds-cal-month {
	box-shadow: var(--elev-1);
	border-color: rgba(21,65,119,.16);
	border-bottom-color: rgba(43,39,35,.16);
	/* Pager newcomers rise as they fade: transform-only keyframe composes
	   with jQuery's inline-opacity fadeIn (animations outrank inline styles,
	   and display:none->block restarts the animation on every reveal). */
	animation: ds-cal-month-in 220ms ease-out both;
}
@keyframes ds-cal-month-in { from { transform: translateY(8px); } }
/* Month title: a full-bleed pale-navy cap distinct from the white body --
   the strongest per-card plane cue. Negative margins match the 24px card
   padding; navy on this tint stays ~8:1. */
.ds-cal-month > h2 {
	margin: -24px -24px 16px;
	padding: 14px 24px 12px;
	background: linear-gradient(180deg, var(--color-primary-tint), #f3f7fb);
	border-bottom: 2px solid rgba(21,65,119,.25);
	border-radius: 11px 11px 0 0;
}
/* Rows: committed warm zebra (the old --color-bg stripe was invisible on
   white), quieter hairline, hover previews the click's lift. */
.ds-cal-row {
	border-bottom-color: #e9e4da;
	transition: background-color 150ms ease, box-shadow 150ms ease, transform 100ms ease;
}
.ds-cal-row:nth-of-type(even) { background: #f6f2ea; }
.ds-cal-row:hover:not([aria-expanded="true"]) {
	background: var(--color-surface);
	box-shadow: 0 1px 3px rgba(43,39,35,.10);
	position: relative;
	z-index: 1;
}
.ds-cal-row:active:not([aria-expanded="true"]) {
	background: #eef2f8;
	box-shadow: inset 0 2px 4px rgba(21,65,119,.14);
	transform: translateY(1px);
}
/* Open row fuses flat-tinted to its detail sheet; the detail itself rises
   as a raised white sheet with a navy spine -- the page's depth moment.
   Keyframes restart when display:none->block re-renders it, so no JS. */
.ds-cal-row[aria-expanded="true"] {
	background-color: var(--color-primary-tint);
	/* app.min.css whitens [aria-expanded="true"] for its own toggle widgets;
	   white on the pale tint was nearly invisible. */
	color: var(--color-text);
	box-shadow: none;
	border-bottom-color: transparent;
}
.ds-cal-detail { transform-origin: top center; }
.ds-cal-detail.is-open {
	background: var(--color-surface);
	border: 1px solid var(--color-border);
	border-left: 3px solid var(--color-primary);
	box-shadow: var(--elev-2);
	animation: ds-cal-detail-in 200ms ease-out both;
}
@keyframes ds-cal-detail-in {
	from { opacity: 0; transform: translateY(-6px) scaleY(.98); }
	to   { opacity: 1; transform: translateY(0)   scaleY(1);   }
}
/* Chevron leans toward its reveal; turns accent-deep once open. */
.ds-cal-row .fa { transition: transform 150ms ease, color 150ms ease; }
.ds-cal-row:hover:not([aria-expanded="true"]) .fa { transform: translateX(2px); color: var(--color-primary); }
.ds-cal-row[aria-expanded="true"] .fa { transform: rotate(90deg); color: var(--color-accent-deep); }
/* The campus chip rides the row like a physical token. */
.ds-cal-row .ds-badge { transition: transform 120ms ease, box-shadow 120ms ease; }
.ds-cal-row:hover .ds-badge,
.ds-cal-row:focus-visible .ds-badge { transform: translateY(-1px); box-shadow: 0 2px 4px rgba(43,39,35,.2); }
/* Pager arrows as physical keys: key-light at rest, lit crest on hover,
   1px press into the page, glyph nudging in the travel direction. */
.ds-cal-nav-btn { transition: background-color 150ms ease, border-color 150ms ease, box-shadow 150ms ease, transform 100ms ease; }
.ds-cal-nav-btn:not(:disabled) { box-shadow: 0 1px 2px rgba(43,39,35,.12); }
.ds-cal-nav-btn:hover:not(:disabled) { transform: translateY(-1px); box-shadow: 0 2px 5px rgba(43,39,35,.16) !important; }
.ds-cal-nav-btn:active:not(:disabled) { transform: translateY(1px) scale(.96); box-shadow: 0 0 1px rgba(43,39,35,.12) !important; }
#ds-cal-prev:active:not(:disabled) .fa { transform: translateX(-2px); }
#ds-cal-next:active:not(:disabled) .fa { transform: translateX(2px); }
/* The gate carries the only navy-chromed shadow; it deepens on focus. */
#ds-cal-campus-gate { box-shadow: var(--elev-navy); }
#ds-cal-campus-gate:focus { box-shadow: 0 2px 4px rgba(13,44,82,.22), 0 10px 24px -8px rgba(13,44,82,.38); }
.ds-cal-program { box-shadow: 0 1px 2px rgba(43,39,35,.06); }
/* Focus = lit orange core plus a soft brand halo (decoration, so it carries
   no contrast duty); :focus-visible keeps the halo keyboard-only. */
.ds-cal-row:focus-visible,
.ds-cal-nav-btn:focus-visible,
.ds-cal-program:focus-visible,
#ds-cal-campus-gate:focus-visible {
	outline: 2px solid var(--color-logo-orange);
	outline-offset: 2px;
	box-shadow: 0 0 0 5px rgba(245,123,32,.25);
}
/* The single interest block: a card of its own, its fields letterpress
   wells that pop to tier-1 on focus. */
.ds-cal-interest {
	margin-top: 8px;
	background: var(--color-surface);
	border: 1px solid var(--color-border);
	border-radius: 12px;
	box-shadow: var(--elev-1);
	padding: 22px 24px;
}
.ds-cal-interest-title {
	font-family: rockwell,Helvetica;
	font-weight: 700;
	color: var(--color-primary);
	font-size: 17px;
	margin: 0 0 12px;
}
.ds-cal-empty-form label.ds-interest-field input,
.ds-cal-empty-form label.ds-interest-field select {
	box-shadow: inset 0 1px 2px rgba(43,39,35,.07);
	transition: box-shadow 150ms ease, border-color 150ms ease;
}
.ds-cal-empty-form label.ds-interest-field input:focus,
.ds-cal-empty-form label.ds-interest-field select:focus {
	box-shadow: 0 1px 3px rgba(43,39,35,.10);
	border-color: var(--color-primary);
}
@media (prefers-reduced-motion: reduce) {
	.ds-cal-row, .ds-cal-row .fa, .ds-cal-row .ds-badge,
	.ds-cal-nav-btn, .ds-cal-nav-btn .fa,
	.ds-cal-detail, .ds-cal-detail.is-open, .ds-cal-month {
		animation: none !important;
		transition: none !important;
	}
}
/* 2026-08-21: equal-height grid rows stretched sparse months (January: two
   rows inside a ~1150px card). start lets each card be its own height. */
.ds-calendar { align-items: start; }
/* Row scannability: a hairline between rows, a warm zebra on alternates, and
   a fixed date column so the program text lines up down the card. */
.ds-cal-row { border-bottom: 1px solid var(--color-border); }
.ds-cal-row:nth-of-type(even) { background: var(--color-bg); }
.ds-cal-row .ds-cal-date { min-width: 52px; }
/* Month header carries its class count as a quiet eyebrow chip. */
.ds-cal-month > h2 {
	display: flex;
	justify-content: space-between;
	align-items: baseline;
	gap: 12px;
}
.ds-cal-count {
	font-family: var(--font-body);
	font-size: 13px;
	font-weight: 600;
	letter-spacing: .06em;
	text-transform: uppercase;
	color: var(--color-muted);
	white-space: nowrap;
}

/* -----------------------------------------------------------------------
 * 1c. Nav clustering + progressive collapse (2026-07-31, user request).
 *
 * The section links (Contact Us / Our Sister School / Medication Aide /
 * Class Calendar) used to sit pinned at the far left of the bar with a
 * dead gap before the account/register controls. Cluster them next to
 * the right-side controls instead: ul.right comes first in the DOM, so
 * floating both groups right yields
 *   [Contact Us | Sister School | Med Aide | Calendar] [Account | Register | menu]
 * The sidr side panel pushes the body aside now (displace:true in
 * app.js) so the navbar squeezes to get out of the way rather than
 * being covered by the panel. (Home's fixed navbar is patched below
 * in 1d because position:fixed elements don't translate with the body
 * margin shift.)
 * --------------------------------------------------------------------- */
#navbar .top-bar-section ul.left {
	float: right !important;
	margin-right: 8px;
}

/* -----------------------------------------------------------------------
 * 1d. Fixed navbar + sidr coexistence (rewritten 2026-08-17).
 *
 * How this actually works, because the previous comment here had it
 * backwards. app.min.css sets `#navbar { position: fixed; width: 100% }`
 * on EVERY page, not just home. When sidr opens it transforms `body`,
 * and a transformed ancestor becomes the containing block for its fixed
 * descendants — so the navbar is dragged along with the body rather than
 * staying glued to the viewport.
 *
 * The old rule assumed the opposite and added `translateX(-260px)` on top
 * of that drag. The bar therefore moved 520px left in total, which is
 * where both reported bugs came from:
 *
 *   - the Alia logo, leftmost in the bar, was carried off the left edge
 *     of the screen and vanished; and
 *   - the bar's right edge stopped short of the drawer, leaving a white
 *     band between the two.
 *
 * What sidr actually does is `body { position: absolute; left: -260px }` —
 * no transform anywhere. A fixed element's containing block is the
 * VIEWPORT, so the navbar is never dragged by that at all. Interior pages
 * only looked dragged because they leave `left: auto`, which resolves to
 * the static position, and the static position follows the shifted body.
 * The home page pins `left: 0`, so it stayed put. Same markup, two
 * different offsets, which is why a single translate could not fix both.
 *
 * So: pin the left edge explicitly and take the drawer's width off the
 * end. The bar squeezes instead of moving, the logo keeps its place on
 * every page, and the right edge lands exactly on the drawer. 200ms
 * matches sidr's own transition.
 * --------------------------------------------------------------------- */
body.sidr-open #navbar {
	left: 0;
	width: calc(100% - 260px);
	transition: width 200ms ease;
}

/* -----------------------------------------------------------------------
 * Progressive collapse: keep the top bar to ONE row, always.
 *
 * Both <ul>s in the bar float right, so the moment they stop fitting side
 * by side the second drops below the first and the bar doubles from 80px
 * to 160px. Measured across widths, that happened at 1100px, 700px and
 * 375px — each just above a Foundation breakpoint that reveals an item
 * before there is room for it.
 *
 * Hiding beats wrapping: every link in `ul.left` also exists in the sidr
 * drawer, which the menu button opens at every width, so nothing becomes
 * unreachable — the bar just stops growing a second storey.
 * --------------------------------------------------------------------- */

/* One threshold, not three. An earlier pass tuned a separate media band to
   each of those ranges, which worked but encoded the pixel width of the
   current nav labels in three places — rename "Our Sister School" and all
   three move. The honest rule is simpler: the secondary group gets shown
   only when there is comfortable room for it, and otherwise lives in the
   drawer where it already exists.

   Raised from 73.75em to 80em when the Blog link joined the group — that is
   the whole point of having one number here rather than three tuned bands. */
@media only screen and (max-width: 80em) {
	#navbar .top-bar-section ul.left { display: none !important; }
}

/* The drawer takes 260px off the bar, but media queries measure the
   VIEWPORT, so the threshold above is 260px too generous while it is open —
   which is how a 1200px window still produced a two-storey bar. The drawer
   supersedes these links anyway. */
body.sidr-open #navbar .top-bar-section ul.left { display: none !important; }

/* -----------------------------------------------------------------------
 * 1e. Let visitors select and copy page text (2026-07-31, user request).
 *
 * app.min.css (the checked-in bundle, compiled from a scss source that
 * isn't in this repo) sets `user-select:none` on `.card` and `.block`.
 * Those started life as drag-ish admin widgets, but on the public site
 * they wrap ordinary prose — the home page's "True Job Placement" and
 * "Alia Advantage" sections, the branch/class/jobs pages, etc. — so
 * nobody could highlight or copy that copy. Interactive chrome that
 * genuinely needs drag-safe text (datepickers, w2ui grids) sets its own
 * user-select and is unaffected. This sheet loads after app.min.css, so
 * an equal-specificity rule wins.
 * --------------------------------------------------------------------- */
.card,
.block {
	-webkit-user-select: text;
	user-select: text;
}

/* ==========================================================================
   §7 — Long-form prose pages (.ds-prose)
   2026-08-21: added for /privacy-policy (adsense-ratings-readiness.md G1
   blocker) and future legal/about pages. Scoped to .ds-prose inside a
   .ds-page so Foundation's global styles keep working everywhere else.
   ========================================================================== */
.ds-page .ds-prose {
	max-width: 760px;
	margin: 0 auto;
	padding: 8px 20px 56px;
	color: var(--color-text, #2b2b2b);
	font-family: var(--font-body, "Source Sans 3", "Segoe UI", Helvetica, Arial, sans-serif);
	font-size: 17px;
	line-height: 1.75;
}
.ds-page .ds-prose h2 {
	font-family: var(--font-headline, rockwell, Helvetica, serif);
	color: var(--color-primary, #154177);
	font-size: 24px;
	margin: 34px 0 10px;
}
.ds-page .ds-prose h2:first-child { margin-top: 8px; }
.ds-page .ds-prose p { margin: 0 0 16px; }
.ds-page .ds-prose ul {
	margin: 0 0 18px;
	padding-left: 22px;
	list-style: disc;
}
.ds-page .ds-prose li { margin-bottom: 10px; }
.ds-page .ds-prose a {
	color: var(--color-primary, #154177);
	text-decoration: underline;
	text-underline-offset: 2px;
}
.ds-page .ds-prose strong { color: inherit; }

/* ==========================================================================
   §7c — Reference-layer chrome (Lighthouse §1.8)
   2026-08-22: review dates / named maintainer / sourced claims / error
   reporting on every maintained reference page. This is what separates a
   reference work from a content farm -- visible currency, visibly owned.
   ========================================================================== */
.ref-meta {
	margin: var(--space-6, 40px) 0 0;
	padding: 14px 18px;
	background: #f4f7fb;
	border-left: 3px solid var(--color-primary, #154177);
	border-radius: 0 8px 8px 0;
	font-size: 14px;
	line-height: 1.6;
	color: #4a5560;
}
.ref-meta__row {
	display: flex;
	flex-wrap: wrap;
	gap: 6px 22px;
}
.ref-meta__item strong { color: var(--color-primary, #154177); }
.ref-meta__sources {
	list-style: none;
	margin: 8px 0 0;
	padding: 0;
	display: flex;
	flex-wrap: wrap;
	gap: 4px 16px;
}
.ref-meta__sources a {
	color: var(--color-primary, #154177);
	text-decoration: underline;
	text-underline-offset: 2px;
}
.ref-meta__err {
	margin: 8px 0 0;
	font-size: 12.5px;
}
.ref-meta__err a { color: var(--color-accent, #f57b20); font-weight: 600; }

/* ==========================================================================
   §7b — Cookie consent banner
   2026-08-21: companion to /privacy-policy + Consent Mode defaults.
   Design tokens only; fixed to viewport bottom; CLS-safe (fixed height,
   no layout shift when it appears over content).
   ========================================================================== */
.consent-banner {
	position: fixed;
	left: 16px;
	right: 16px;
	bottom: 16px;
	z-index: 99990;
	max-width: 340px;
	margin: 0 auto;
	background: #ffffff;
	border: 1px solid var(--color-primary, #154177);
	border-radius: 10px;
	box-shadow: var(--elev-2, 0 8px 24px rgba(13, 44, 82, .18));
	padding: 14px 16px;
	font-family: var(--font-body, "Source Sans 3", "Segoe UI", Helvetica, Arial, sans-serif);
}
.consent-banner__text {
	margin: 0 0 10px;
	font-size: 13.5px;
	line-height: 1.5;
	color: #333;
}
.consent-banner__text a {
	color: var(--color-primary, #154177);
	text-decoration: underline;
}
.consent-banner__actions {
	display: flex;
	gap: 8px;
	justify-content: flex-end;
}
.consent-btn {
	border-radius: 6px;
	padding: 7px 14px;
	font-size: 13.5px;
	font-weight: 600;
	cursor: pointer;
	border: 1.5px solid var(--color-primary, #154177);
	background: #fff;
	color: var(--color-primary, #154177);
}
.consent-btn:hover { background: #f2f6fb; }
.consent-btn--allow {
	background: var(--color-primary, #154177);
	color: #fff;
}
.consent-btn--allow:hover { background: var(--color-primary-deep, #0d2c52); }
/* 2026-08-22 v2: Customize opens the per-category panel. Decline and
   Accept all keep equal visual weight on layer 1 (GDPR dark-pattern
   rule: refusing must be as easy as accepting). Customize is the quiet
   third action. */
.consent-btn--config {
	border-color: transparent;
	text-decoration: underline;
	text-underline-offset: 2px;
}
.consent-btn--config:hover { background: transparent; color: var(--color-primary-deep, #0d2c52); }
.consent-prefs {
	margin-top: 12px;
	border-top: 1px solid #dfe6f0;
	padding-top: 10px;
}
.consent-prefs__list {
	list-style: none;
	margin: 0;
	padding: 0;
}
.consent-cat {
	padding: 9px 0;
	border-bottom: 1px solid #eef2f8;
}
.consent-cat:last-child { border-bottom: 0; }
.consent-cat__desc {
	margin: 6px 0 0 44px;
	font-size: 13px;
	line-height: 1.45;
	color: #66707d;
}
/* Toggle switch. The necessary row's control is disabled + grayed: it is
   disclosure, not a choice. */
.consent-toggle {
	display: flex;
	align-items: center;
	gap: 10px;
	cursor: pointer;
}
.consent-toggle input {
	position: absolute;
	opacity: 0;
	width: 1px;
	height: 1px;
}
.consent-toggle__track {
	flex: 0 0 auto;
	width: 34px;
	height: 20px;
	border-radius: 10px;
	background: #b9c4d2;
	position: relative;
	transition: background .15s ease;
}
.consent-toggle__track::after {
	content: "";
	position: absolute;
	top: 2px;
	left: 2px;
	width: 16px;
	height: 16px;
	border-radius: 50%;
	background: #fff;
	box-shadow: 0 1px 2px rgba(13, 44, 82, .3);
	transition: left .15s ease;
}
.consent-toggle input:checked + .consent-toggle__track {
	background: var(--color-primary, #154177);
}
.consent-toggle input:checked + .consent-toggle__track::after { left: 16px; }
.consent-toggle input:focus-visible + .consent-toggle__track {
	outline: 2px solid var(--color-accent, #f57b20);
	outline-offset: 2px;
}
.consent-toggle input:disabled + .consent-toggle__track {
	background: #dde3ea;
	opacity: .75;
	cursor: not-allowed;
}
.consent-toggle input:disabled ~ .consent-toggle__label {
	color: #98a2af;
}
.consent-toggle__label {
	font-size: 13.5px;
	font-weight: 700;
	color: var(--color-primary, #154177);
}
.consent-prefs__actions {
	display: flex;
	gap: 8px;
	justify-content: space-between;
	align-items: center;
	margin-top: 12px;
	flex-wrap: wrap;
}
.consent-btn--necessary {
	border-color: #b9c4d2;
	color: #4a5560;
	font-weight: 500;
}
.consent-btn--necessary:hover { background: #f2f6fb; }
.consent-btn--save {
	background: var(--color-accent, #f57b20);
	border-color: var(--color-accent, #f57b20);
	color: #fff;
}
.consent-btn--save:hover { background: #d96a15; }
@media (max-width: 420px) {
	.consent-banner { left: 10px; right: 10px; bottom: 10px; }
}
