/* ==========================================================================
   SakuraBot — Super Chibi Edition
   Shared stylesheet for index.html and details.html
   ==========================================================================

   CHANGES FROM THE SINGLE-FILE CONCEPT (all deliberate — see notes):

   1. No Google Fonts request. Wikimedia tools shouldn't pull resources from
      third-party servers; every visitor's IP would be handed to Google.
      A rounded system stack is used instead. To get real Nunito back,
      self-host it — see the @font-face block below.

   2. prefers-reduced-motion is honoured. The floating mascot and pulsing dot
      are lovely but can be genuinely unpleasant for some people.

   3. Chunky focus rings, print styles, mobile shadow scaling.

   THE PALETTE IS UNCHANGED from the original concept — same pinks, same hot
   #ff3366 links, same white-on-colour tags. See the note at the bottom of this
   file if you ever want the low-contrast tags looked at; nothing is changed
   for now.
   ========================================================================== */

/* --- Optional: self-hosted Nunito -----------------------------------------
   Download the .woff2 files from fonts.google.com, drop them next to this
   file, and uncomment. Then the site keeps its bubbly font with no external
   requests at all.

@font-face {
	font-family: 'Nunito';
	src: url('nunito-600.woff2') format('woff2');
	font-weight: 600; font-display: swap;
}
@font-face {
	font-family: 'Nunito';
	src: url('nunito-800.woff2') format('woff2');
	font-weight: 800; font-display: swap;
}
@font-face {
	font-family: 'Nunito';
	src: url('nunito-900.woff2') format('woff2');
	font-weight: 900; font-display: swap;
}
--------------------------------------------------------------------------- */

/* ─── Tokens ─────────────────────────────────────────────────────────────── */
:root {
	/* ink & paper */
	--ink:          #2b1910;   /* espresso — borders, headings, body */
	--ink-light:    #6a4128;
	--paper:        #ffffff;
	--bg:           #ffe4e6;
	--dot:          #ffb3c6;

	/* pop palette — exactly as the original concept */
	--pop:          #ff3366;   /* hot pink: links, shadows, fills — UNCHANGED */
	/* Link *text* only. The fills above stay the original #ff3366; this one is
	   a touch deeper so link text clears WCAG AA on white (4.7:1, where the
	   original hot pink was 3.55:1 — the last Lighthouse accessibility flag).
	   Same hue, so links still read as the brand pink beside the fills. */
	--pop-ink:      #e5004e;
	--soft:         #ffc2d1;
	--orange:       #ff8800;
	--lemon:        #ffde00;
	--blue:         #00d2ff;
	--mint:         #2ed573;
	--amber:        #ffa502;

	/* The only colour added to your palette. Used strictly for failures —
	   nothing decorative. Deep enough to read as an alarm, still in the pink
	   family so it doesn't fight the rest. Change this one hex to retune. */
	--alert:        #d81b3c;

	/* Text on the bright chips. Espresso ink on every fill — it passes WCAG AA
	   on all of them (4.7:1 to 12.6:1) where white was failing (white on cyan
	   was 1.8:1, the Lighthouse flag), and dark-ink-on-bright is the classic
	   pop-art look anyway. Change back to #ffffff if you ever want white. */
	--tag-text:     #2b1910;
	--on-bright:    #2b1910;

	/* structure */
	--bw:           5px;
	--border:       var(--bw) solid var(--ink);
	--r-lg:         40px;
	--r-md:         24px;
	--r-sm:         12px;
	--pop-shadow:   16px 16px 0 var(--pop);
	--ink-shadow:   8px 8px 0 var(--ink);

	--font: 'Nunito', 'Nunito Sans', 'Varela Round', ui-rounded,
	        'Segoe UI Rounded', 'Trebuchet MS', system-ui, sans-serif;
}

/* No automatic dark mode — the pink scheme renders identically whatever the
   visitor's system theme is set to. (An earlier draft flipped to a dark
   palette on dark-mode machines; that's been removed.) */

* { box-sizing: border-box; }

html { scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }

body {
	margin: 0;
	padding: 40px 20px;
	font-family: var(--font);
	color: var(--ink);
	background-color: var(--bg);
	/* manga screentone */
	background-image: radial-gradient(var(--dot) 20%, transparent 20%);
	background-size: 28px 28px;
	overflow-x: hidden;
}

a { color: var(--pop-ink); text-decoration: none; font-weight: 900;
	border-radius: 3px;
	transition: background-color .15s ease, box-shadow .15s ease, transform .15s ease; }
a:hover {
	/* Pink highlight for LINKS. Deliberately different from the lemon used by
	   <code> words, so hovering a link never looks like a code snippet. The
	   box-shadow gives a little bleed without the layout shift padding caused. */
	background: var(--soft);
	color: var(--ink);
	box-shadow: 0 0 0 3px var(--soft);
}

/* "grow" affordance so links clearly read as clickable. Only on the short,
   single-word link clusters — never inline prose links, which would reflow /
   overflow on very narrow screens. */
.card-links a,
.footer a,
.stop a { display: inline-block; }
.card-links a:hover,
.footer a:hover,
.stop a:hover { transform: scale(1.12); }

/* chunky focus ring — fits the style and makes keyboard use obvious */
a:focus-visible,
button:focus-visible,
[tabindex]:focus-visible {
	outline: 4px solid var(--blue);
	outline-offset: 3px;
	border-radius: 4px;
}

code {
	font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
	font-weight: 700;
	font-size: .9em;
	background: var(--lemon);
	color: var(--on-bright);
	border: 2px solid var(--ink);
	border-radius: 6px;
	padding: 0 5px;
}

/* skip link — hidden until focused */
.skip {
	position: absolute;
	left: -9999px;
	top: 10px;
	background: var(--lemon);
	color: var(--on-bright);
	border: var(--border);
	border-radius: var(--r-sm);
	padding: 10px 18px;
	font-weight: 900;
	z-index: 99;
}
.skip:focus { left: 20px; }

/* ─── Shell ──────────────────────────────────────────────────────────────── */
.dashboard {
	max-width: 1000px;
	margin: 0 auto;
	background: var(--paper);
	border: var(--border);
	border-radius: var(--r-lg);
	box-shadow: var(--pop-shadow);
	padding-bottom: 20px;
}

/* ─── Hero ───────────────────────────────────────────────────────────────── */
.hero {
	background: var(--soft);
	border-bottom: var(--border);
	border-radius: 35px 35px 0 0;
	padding: 50px 6%;
	display: flex;
	justify-content: space-between;
	align-items: center;
	flex-wrap: wrap;
	gap: 30px;
}

.hero-text { flex: 1; min-width: 280px; }

.hero-text h1 {
	font-size: clamp(3rem, 8vw, 5.5rem);
	font-weight: 900;
	margin: 0 0 15px 0;
	color: var(--paper);
	letter-spacing: -2px;
	text-transform: uppercase;
	-webkit-text-stroke: 3px var(--ink);
	paint-order: stroke fill;   /* keeps the stroke from eating the letterforms */
	text-shadow: 6px 6px 0 var(--ink);
	line-height: 1;
}

.kicker {
	font-size: 1.15rem;
	font-weight: 900;
	margin: 0;
	color: var(--on-bright);
	background: var(--lemon);
	display: inline-block;
	padding: 4px 12px;
	border: 3px solid var(--ink);
	border-radius: var(--r-sm);
	transform: rotate(-2deg);
	text-transform: uppercase;
	letter-spacing: .5px;
}

.hero-back { margin-top: 18px; font-size: 1.05rem; }

/* Status pill */
.status-pill {
	background: var(--paper);
	border: var(--border);
	border-radius: 50px;
	padding: 12px 26px;
	font-size: 1.05rem;
	font-weight: 900;
	display: inline-flex;
	align-items: center;
	gap: 14px;
	box-shadow: 6px 6px 0 var(--ink);
	margin-top: 25px;
	max-width: 100%;
}
/* the status pill is a read-out, not a button — it must not move on hover */
.status-pill .txt { min-width: 0; overflow-wrap: anywhere; }

.indicator {
	width: 20px; height: 20px;
	background: var(--mint);
	border: 4px solid var(--ink);
	border-radius: 50%;
	flex: 0 0 auto;
	animation: pulse 1s infinite alternate;
}
.indicator.off  { background: var(--amber); animation: none; }
/* overdue — yellow, and it keeps moving so it reads differently from standby */
.indicator.warn { background: var(--lemon); animation: pulse-warn 1.4s infinite alternate; }
/* failed */
.indicator.bad  { background: var(--alert); animation: pulse-bad 0.7s infinite alternate; }

@keyframes pulse {
	0%   { transform: scale(1);   box-shadow: 0 0 0 var(--mint); }
	100% { transform: scale(1.2); box-shadow: 0 0 15px var(--mint); }
}
@keyframes pulse-warn {
	0%   { transform: scale(1);    box-shadow: 0 0 0 var(--lemon); }
	100% { transform: scale(1.18); box-shadow: 0 0 14px var(--lemon); }
}
@keyframes pulse-bad {
	0%   { transform: scale(1);   box-shadow: 0 0 0 var(--alert); }
	100% { transform: scale(1.2); box-shadow: 0 0 16px var(--alert); }
}

/* Mascot */
.hero-icon {
	font-size: 5rem;
	background: var(--paper);
	border: var(--border);
	border-radius: 40%;
	width: 140px; height: 140px;
	display: flex; align-items: center; justify-content: center;
	box-shadow: var(--ink-shadow);
	animation: float 3s ease-in-out infinite;
	flex: 0 0 auto;
	z-index: 2;
}
.hero-icon.sm { width: 100px; height: 100px; font-size: 3.4rem; }

/* the mascot is decoration, not text — no I-beam cursor, no selecting it */
.hero-icon { cursor: default; }
.hero-icon .mascot-svg { pointer-events: none; user-select: none; }

/* ─── Mascot expressions ──────────────────────────────────────────────────
   One SVG, several faces. app.js puts is-running / is-ok / is-overdue /
   is-failed / is-unknown on .hero-icon and the right bits show. Default (no
   class, before the script runs) is a peaceful sleeping face. */
.mascot-svg { display: block; overflow: visible; }
.hero-icon.sm .mascot-svg { width: 66px; height: 66px; }

/* hidden until a state asks for them */
.hero-icon .m-eyes-open,
.hero-icon .m-mouth-worried,
.hero-icon .m-mouth-o,
.hero-icon .m-zzz,
.hero-icon .m-sweat,
.hero-icon .m-sparkle { display: none; }

/* running — awake, calm smile, a twinkle */
.hero-icon.is-running .m-eyes-shut { display: none; }
.hero-icon.is-running .m-eyes-open { display: block; }
.hero-icon.is-running .m-sparkle {
	display: block;
	transform-origin: 26px 27px;
	animation: m-twinkle 1.1s ease-in-out infinite;
}

/* ok / standby — asleep, little zzz drifting up */
.hero-icon.is-ok .m-zzz { display: block; }
.hero-icon.is-ok .m-zzz text { animation: m-drift 2.6s ease-in-out infinite; }
.hero-icon.is-ok .m-zzz text:nth-child(2) { animation-delay: .5s; }
.hero-icon.is-ok .m-zzz text:nth-child(3) { animation-delay: 1s; }

/* overdue — awake and a bit worried */
.hero-icon.is-overdue .m-eyes-shut { display: none; }
.hero-icon.is-overdue .m-eyes-open { display: block; }
.hero-icon.is-overdue .m-mouth-calm { display: none; }
.hero-icon.is-overdue .m-mouth-worried { display: block; }

/* failed — awake, worried, a nervous sweat drop */
.hero-icon.is-failed .m-eyes-shut { display: none; }
.hero-icon.is-failed .m-eyes-open { display: block; }
.hero-icon.is-failed .m-mouth-calm { display: none; }
.hero-icon.is-failed .m-mouth-worried { display: block; }
.hero-icon.is-failed .m-sweat { display: block; animation: m-sweat-drop 1.6s ease-in-out infinite; }

/* unknown / offline — dozing, small neutral mouth, no zzz */
.hero-icon.is-unknown .m-mouth-calm { display: none; }
.hero-icon.is-unknown .m-mouth-o { display: block; }

@keyframes m-twinkle {
	0%, 100% { opacity: .25; transform: scale(.7) rotate(0deg); }
	50%      { opacity: 1;   transform: scale(1.1) rotate(45deg); }
}
@keyframes m-drift {
	0%   { opacity: 0; transform: translate(0, 0); }
	30%  { opacity: 1; }
	100% { opacity: 0; transform: translate(4px, -6px); }
}
@keyframes m-sweat-drop {
	0%, 100% { transform: translateY(0);   opacity: .9; }
	50%      { transform: translateY(2px); opacity: 1; }
}

@media (prefers-reduced-motion: reduce) {
	.hero-icon .m-sparkle,
	.hero-icon .m-zzz text,
	.hero-icon .m-sweat { animation: none !important; }
	.card-links a:hover,
	.footer a:hover,
	.stop a:hover { transform: none; }
}

@keyframes float {
	0%, 100% { transform: translateY(0) rotate(5deg); }
	50%      { transform: translateY(-15px) rotate(-5deg); }
}

@media (prefers-reduced-motion: reduce) {
	.hero-icon, .indicator, .status-pill, .task-card {
		animation: none !important;
		transition: none !important;
	}
	.task-card:hover, .task-card:focus-within { transform: none; }
}

/* ─── Content ────────────────────────────────────────────────────────────── */
.content { padding: 50px 6%; }

h2 {
	font-size: 2rem;
	font-weight: 900;
	text-transform: uppercase;
	margin: 0 0 25px;
	display: flex;
	align-items: center;
	gap: 15px;
	letter-spacing: -.5px;
}
h2::before { content: '✨'; font-size: 1.6rem; }
h2.map::before   { content: '🗺️'; }
h2.warn::before  { content: '📣'; }

.section { margin-bottom: 55px; }
.section:last-child { margin-bottom: 0; }

/* Speech bubble */
.intro-speech {
	background: var(--paper);
	border: var(--border);
	border-radius: 30px;
	padding: 30px;
	font-size: 1.15rem;
	font-weight: 800;
	line-height: 1.65;
	margin-bottom: 60px;
	box-shadow: 8px 8px 0 var(--pop);
}

/* ─── Task cards (manga panels) ──────────────────────────────────────────── */
.task-grid {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
	gap: 30px;
}

.task-card {
	background: var(--paper);
	border: var(--border);
	border-radius: var(--r-md);
	padding: 32px 25px 25px;
	box-shadow: var(--ink-shadow);
	transition: box-shadow .2s;
	position: relative;
	overflow: hidden;
}

/* colour bar along the top of each panel */
.task-card::before {
	content: '';
	position: absolute;
	top: 0; left: 0; width: 100%; height: 12px;
	background: var(--orange);
	border-bottom: 4px solid var(--ink);
}
.task-card.c-blue::before  { background: var(--blue); }
.task-card.c-lemon::before { background: var(--lemon); }
.task-card.c-mint::before  { background: var(--mint); }

/* The whole card isn't a single link (it holds several), so it must NOT move
   on hover — only its actual links respond. This avoids the "why is this
   moving if I can't click it?" confusion. */

.task-card h3 {
	font-size: 1.45rem;
	font-weight: 900;
	margin: 8px 0 6px;
	text-transform: uppercase;
	letter-spacing: -.5px;
}
.task-card h3 a { color: inherit; }
.task-card h3 a:hover { background: var(--soft); color: var(--ink); }

.task-card p {
	font-size: 1.02rem;
	font-weight: 600;
	color: var(--ink-light);
	line-height: 1.55;
	margin: 0 0 18px;
}

/* little "every day / every week" stamp */
.cycle {
	display: inline-block;
	font-size: .78rem;
	font-weight: 900;
	text-transform: uppercase;
	letter-spacing: 1px;
	background: var(--ink);
	color: var(--paper);
	border-radius: 50px;
	padding: 3px 12px;
	margin-bottom: 10px;
}

/* "See it live: simple · ckb …" row under a card's wiki chips */
.card-links {
	margin-top: 14px;
	font-size: .85rem;
	font-weight: 700;
	color: var(--ink-light);
	line-height: 1.55;
}
.card-links a { color: var(--pop-ink); white-space: nowrap; }

/* "last run 3 days ago" stamp, filled in by app.js.
   Stays invisible when empty so the card doesn't hold a gap for it. */
.card-status {
	display: block;
	width: fit-content;
	margin-top: 14px;
	background: transparent;
	color: var(--ink-light);
	border: 3px dashed var(--ink);
	padding: 2px 11px;
}
.card-status:empty { display: none; }

/* stamp variants by state */
.card-status.s-running { background: var(--mint);  color: var(--ink); border-style: solid; }
.card-status.s-overdue { background: var(--lemon); color: var(--ink); border-style: solid; }
.card-status.s-failed  { background: var(--alert); color: #fff;       border-style: solid; }
.card-status.s-unknown { border-style: dotted; }
.card-status.s-paused  { background: var(--bg); color: var(--ink-light); border-style: solid; }

/* ─── Task-card health states ────────────────────────────────────────────
   Only the colour bar and the drop shadow change, so a healthy card looks
   exactly as it always did. A card in trouble is impossible to scroll past. */

.task-card.is-running::before { background: var(--mint); }

/* overdue: a hazard stripe, so it can't be mistaken for one of the normal
   card colours no matter which card it lands on */
.task-card.is-overdue::before {
	background: repeating-linear-gradient(
		45deg,
		var(--lemon) 0 12px,
		var(--ink)   12px 20px
	);
}
.task-card.is-overdue { box-shadow: 8px 8px 0 var(--lemon); }

.task-card.is-failed::before { background: var(--alert); height: 16px; }
.task-card.is-failed {
	box-shadow: 8px 8px 0 var(--alert);
	border-color: var(--alert);
}
.task-card.is-failed:hover,
.task-card.is-failed:focus-within { box-shadow: 14px 14px 0 var(--alert); }

.task-card.is-overdue:hover,
.task-card.is-overdue:focus-within { box-shadow: 14px 14px 0 var(--lemon); }

/* ─── Health banner ──────────────────────────────────────────────────────
   Hidden entirely when everything is fine — no permanent "all good" panel
   taking up space and training people to ignore it. */

.health {
	background: var(--paper);
	border: var(--border);
	border-radius: var(--r-md);
	padding: 22px 26px;
	margin-bottom: 26px;
	box-shadow: var(--ink-shadow);
}
.health[hidden] { display: none !important; }

.health.is-failed  { border-color: var(--alert); box-shadow: 8px 8px 0 var(--alert); }
.health.is-overdue { box-shadow: 8px 8px 0 var(--lemon); }
.health.is-unknown { box-shadow: 8px 8px 0 var(--ink); }

.health h3 {
	margin: 0 0 12px;
	font-size: 1.3rem;
	font-weight: 900;
	text-transform: uppercase;
	letter-spacing: -.5px;
}
.health.is-failed h3 { color: var(--alert); }

.health ul { margin: 0; padding-left: 22px; font-weight: 600; line-height: 1.55; }
.health li { margin-bottom: 10px; }
.health li:last-child { margin-bottom: 0; }
.health li b { font-weight: 900; }

.health code {
	display: inline-block;
	margin-top: 6px;
	background: var(--bg);
	border-color: var(--ink);
	font-size: .85em;
	word-break: break-word;
}

.health-foot {
	margin: 14px 0 0;
	padding-top: 12px;
	border-top: 3px dashed var(--ink);
	font-size: .88rem;
	font-weight: 700;
	color: var(--ink-light);
}

/* ─── "More tasks" strip ──────────────────────────────────────────────────
   Sits under the task grid and points at the quieter jobs. Deliberately NOT a
   card: dashed instead of solid, no drop shadow, one line tall. It should read
   as a signpost, not compete with the real work above it — which is the whole
   reason those jobs were moved off this page. */
.more-link {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 18px;
	margin-top: 26px;
	padding: 16px 22px;
	background: var(--paper);
	border: 4px dashed var(--ink);
	border-radius: var(--r-md);
	color: var(--ink);
	font-weight: 700;
	transition: background .15s, border-color .15s;
}
.more-link:hover,
.more-link:focus-visible {
	background: var(--bg);
	border-color: var(--pop);
	color: var(--ink);
	box-shadow: none;
}
.more-text {
	min-width: 0;
	color: var(--ink);
	font-weight: 900;
	font-size: 1.02rem;
	text-transform: uppercase;
	letter-spacing: -.3px;
	overflow-wrap: anywhere;
}
.more-go {
	flex: 0 0 auto;
	font-size: 1.5rem;
	font-weight: 900;
	color: var(--pop-ink);
	transition: transform .15s;
}
.more-link:hover .more-go { transform: translateX(5px); }

@media (prefers-reduced-motion: reduce) {
	.more-link:hover .more-go { transform: none; }
}
@media (hover: none) {
	.more-link:hover .more-go { transform: none; }
}

/* ─── Tags ───────────────────────────────────────────────────────────────── */
.tags-container { display: flex; flex-wrap: wrap; gap: 8px; }

.wiki-tag {
	display: inline-block;
	background: var(--pop);
	color: var(--tag-text);
	padding: 6px 14px;
	border-radius: 50px;
	border: 3px solid var(--ink);
	font-size: .85rem;
	font-weight: 900;
	text-transform: uppercase;
	letter-spacing: .5px;
}
.wiki-tag.alt1 { background: var(--orange); }
.wiki-tag.alt2 { background: var(--blue); }
.wiki-tag.alt3 { background: var(--lemon); color: var(--ink); }

/* ─── Coverage strip ─────────────────────────────────────────────────────── */
.stops { display: grid; gap: 14px; }

.stop {
	display: flex;
	align-items: center;
	gap: 16px;
	background: var(--paper);
	border: var(--border);
	border-radius: var(--r-md);
	padding: 14px 18px;
	box-shadow: 5px 5px 0 var(--ink);
}
.stop-code {
	flex: 0 0 auto;
	min-width: 74px;
	text-align: center;
	background: var(--blue);
	color: var(--tag-text);
	border: 3px solid var(--ink);
	border-radius: 50px;
	padding: 5px 10px;
	font-weight: 900;
	font-size: .9rem;
	text-transform: uppercase;
}
.stop:nth-child(2) .stop-code { background: var(--pop); }
.stop:nth-child(3) .stop-code { background: var(--orange); }
.stop:nth-child(4) .stop-code { background: var(--lemon); color: var(--ink); }
.stop:nth-child(5) .stop-code { background: var(--mint); }

.stop-name { font-weight: 900; font-size: 1.05rem; }
.stop-sub  { font-weight: 600; font-size: .92rem; color: var(--ink-light); }

/* ─── Notice panels ──────────────────────────────────────────────────────── */
.notice {
	background: var(--paper);
	border: var(--border);
	border-radius: var(--r-md);
	padding: 26px 28px;
	box-shadow: var(--ink-shadow);
	margin-bottom: 22px;
}
.notice:last-child { margin-bottom: 0; }
.notice.shout { box-shadow: 8px 8px 0 var(--pop); }

.notice h3 {
	font-size: 1.3rem;
	font-weight: 900;
	text-transform: uppercase;
	margin: 0 0 10px;
	display: flex; align-items: center; gap: 10px;
	letter-spacing: -.5px;
}
.notice p { margin: 0 0 12px; font-weight: 600; font-size: 1.02rem; line-height: 1.6; }
.notice p:last-child { margin-bottom: 0; }

/* ─── Details page: panels ───────────────────────────────────────────────── */
.panel {
	background: var(--paper);
	border: var(--border);
	border-radius: var(--r-md);
	box-shadow: var(--ink-shadow);
	margin-bottom: 30px;
	overflow: hidden;
	scroll-margin-top: 24px;
}

.panel-head {
	background: var(--soft);
	border-bottom: var(--border);
	padding: 18px 26px;
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 14px;
	flex-wrap: wrap;
}
.panel-head h3 {
	margin: 0;
	font-size: 1.4rem;
	font-weight: 900;
	text-transform: uppercase;
	letter-spacing: -.5px;
	color: var(--on-bright);
}

.panel-body { padding: 26px; }
.panel-body p { font-weight: 600; font-size: 1.02rem; line-height: 1.65; margin: 0 0 15px; }
.panel-body p:last-child { margin-bottom: 0; }
.panel-body ul { margin: 0 0 15px; padding-left: 22px; font-weight: 600; line-height: 1.6; }
.panel-body ul li { margin-bottom: 8px; }

/* fact chips */
.facts { display: flex; flex-wrap: wrap; gap: 10px; margin-bottom: 20px; }
.fact {
	background: var(--bg);
	border: 3px solid var(--ink);
	border-radius: var(--r-sm);
	padding: 7px 13px;
	font-size: .88rem;
	line-height: 1.3;
	color: var(--on-bright);
}
.fact b { display: block; font-size: .7rem; text-transform: uppercase; letter-spacing: 1px; opacity: .75; }
.fact span { font-weight: 900; }

/* Chapter divider on the details page.
   It is a real <h2> so the page runs h1 → h2 → h3 in order (a screen reader
   announces the chapters as the sections they are, and Lighthouse no longer
   reports a skipped heading level). The rules below undo the global h2 look —
   the pill keeps exactly the appearance it always had. */
h2.chapter,
.chapter {
	font-size: 1rem;
	font-weight: 900;
	text-transform: uppercase;
	letter-spacing: 3px;
	background: var(--ink);
	color: var(--paper);
	display: inline-block;
	padding: 7px 20px;
	border-radius: 50px;
	margin: 45px 0 22px;
	gap: 0;
}
h2.chapter::before { content: none; }   /* no ✨ on a chapter pill */
.chapter.first { margin-top: 0; }

/* ─── Footer ─────────────────────────────────────────────────────────────── */
.footer {
	text-align: center;
	padding: 28px 20px;
	font-weight: 900;
	font-size: 1.05rem;
	color: var(--on-bright);
	background: var(--soft);
	border-top: var(--border);
	border-radius: 0 0 35px 35px;
	text-transform: uppercase;
	letter-spacing: 2px;
}
.footer .fine {
	display: block;
	margin-top: 8px;
	font-size: .74rem;
	letter-spacing: .5px;
	text-transform: none;
	font-weight: 700;
	color: var(--ink-light);
}

/* Links that sit on a pink band rather than on white. Pink-on-pink measured
   2.35:1 in the footer and 3.13:1 for the hero "back" link, both under the
   4.5:1 minimum — the last accessibility flags on the details and run-pages
   screens. Espresso ink clears AA comfortably on both bands, and the underline
   keeps them obviously clickable now they are no longer a separate colour. */
.footer a,
.hero-back a {
	color: var(--on-bright);
	text-decoration: underline;
	text-underline-offset: 3px;
	text-decoration-thickness: 2px;
}
.footer a:hover,
.footer a:focus-visible,
.hero-back a:hover,
.hero-back a:focus-visible { background: var(--paper); color: var(--ink); }

/* ─── Overflow hardening ──────────────────────────────────────────────────
   Keeps everything inside the pink shell even at absurd viewport widths.
   The site is fluid, but a few things could still push past the edge:  */

/* 1. The hero text used to DEMAND 280px even on a 120px screen — the single
      biggest cause of overflow. Now it never asks for more than it has. */
.hero-text { min-width: min(280px, 100%); }

/* 2. Long words, URLs and code wrap instead of stretching their container. */
.intro-speech, .task-card p, .notice p, .notice h3,
.panel-body, .panel-body li, .panel-head h3,
.stop-name, .stop-sub, .card-links, .health, .health li,
.fact, .footer, code {
	overflow-wrap: break-word;
	word-break: break-word;
}

/* 3. Flex children that hold text must be allowed to shrink below their
      content width (otherwise they overflow the row). This covers every flex
      row on the site, so nothing is pushed past the edge at extreme widths. */
.stop, .stop > div,
.status-pill, .status-pill .txt,
.panel-head, .facts, .fact, .tags-container,
.hero, .hero-text { min-width: 0; }

/* 4. As a last resort the big title and any long word may break rather than
      spill off the side. */
.hero-text h1, .card-status, .cycle, .wiki-tag,
.fact span, .fact b { overflow-wrap: anywhere; word-break: break-word; }

/* 5. Media never exceeds its box (the body already blocks sideways scroll). */
.hero-icon .mascot-svg, img { max-width: 100%; }

/* ─── Responsive ─────────────────────────────────────────────────────────── */
@media (max-width: 780px) {
	body { padding: 16px 10px; }

	:root {
		--bw: 4px;
		--r-lg: 28px;
		--pop-shadow: 8px 8px 0 var(--pop);
		--ink-shadow: 5px 5px 0 var(--ink);
	}

	.dashboard { border-radius: 28px; }
	.hero { padding: 34px 7%; border-radius: 24px 24px 0 0; gap: 22px; }
	.hero-text h1 { -webkit-text-stroke-width: 2px; text-shadow: 4px 4px 0 var(--ink); }
	.hero-icon { width: 96px; height: 96px; font-size: 3.4rem; }
	.hero-icon.sm { width: 76px; height: 76px; font-size: 2.6rem; }

	.content { padding: 34px 7%; }
	h2 { font-size: 1.6rem; }
	.intro-speech { padding: 22px; font-size: 1.05rem; margin-bottom: 42px; }

	/* Centre the hero on phones — the mascot sits under a centred title
	   instead of hanging off to one side. */
	.hero { flex-direction: column; align-items: center; text-align: center; }
	.hero-text { align-items: center; }
	.hero-back, .kicker { align-self: center; }

	.task-grid { gap: 20px; }
	.task-card { padding: 28px 20px 20px; }
	.section { margin-bottom: 40px; }

	.stop { flex-wrap: wrap; gap: 10px; }
	.footer { border-radius: 0 0 24px 24px; letter-spacing: 1px; font-size: .95rem; }
	.panel-body, .notice { padding: 20px; }
	.chapter { margin: 32px 0 18px; }
}

@media (max-width: 420px) {
	.hero-text h1 { font-size: 2.6rem; }
	.status-pill { font-size: .92rem; padding: 10px 18px; gap: 10px; }
	.chapter { letter-spacing: 1.5px; font-size: .85rem; }
}

/* very narrow (small phones, split-screen, devtools) — shrink so nothing
   overflows even here */
@media (max-width: 360px) {
	body { padding: 10px 6px; }
	.hero { padding: 24px 6%; gap: 16px; }
	.hero-text h1 { font-size: 2rem; -webkit-text-stroke-width: 1.5px; letter-spacing: -1px; }
	.hero-icon { width: 66px; height: 66px; }
	.hero-icon .mascot-svg { width: 52px; height: 52px; }
	.status-pill { font-size: .8rem; padding: 8px 13px; gap: 9px; }
	.content { padding: 26px 6%; }
	.intro-speech { padding: 18px; font-size: 1rem; }
	.card-links { font-size: .8rem; }
	.kicker { font-size: 1rem; }
}

/* ─── Touch devices ───────────────────────────────────────────────────────
   On a phone/tablet there's no real hover — a tap would otherwise leave the
   card stuck in its tilted "hover" pose. Turn the hover motion off where the
   pointer can't hover, so cards sit still on touch. */
@media (hover: none) {
	.task-card:hover,
	.task-card:focus-within {
		transform: none;
		box-shadow: var(--ink-shadow);
	}
	.card-links a:hover,
	.footer a:hover,
	.stop a:hover { transform: none; }
	a:hover { background: transparent; box-shadow: none; color: var(--pop-ink); }
}

/* ─── Print ──────────────────────────────────────────────────────────────── */
@media print {
	body { background: #fff; padding: 0; }
	.dashboard { border: 2px solid #000; box-shadow: none; max-width: none; }
	.task-card, .notice, .panel, .stop { box-shadow: none; break-inside: avoid; }
	.hero-icon, .indicator, .skip { display: none; }
	a { color: #000; text-decoration: underline; }
}

/* ==========================================================================
   NOTE ON THE TAG COLOURS  (nothing below is active — reference only)

   The palette is yours and it stays as it is. One thing worth knowing, for
   whenever you feel like it: white text on the lighter fills is hard to read
   for some people — white on --blue is 1.8:1 and white on --orange is 2.4:1,
   where the usual readability floor is 4.5:1. The pink and lemon tags are
   fine.

   If you ever want to fix that without touching a single colour, flip the
   tag text to espresso on the two light fills. Dark ink on bright fills is
   very much still the pop-art look:

       .wiki-tag.alt1,
       .wiki-tag.alt2,
       .stop:nth-child(3) .stop-code,
       .stop:nth-child(5) .stop-code { color: var(--on-bright); }

   Uncomment that, or don't — the site works either way.
   ========================================================================== */
