/*
 * A Shop for Moguls — the whole design system, in one file.
 *
 * This is the MXMINI system, verbatim: warm-black that leans brown, one
 * terracotta accent, a bone page. Cards get a border, not a shadow.
 * Buttons are 6px rectangles that do not move. Emoji are the icon set.
 * Display type is Archivo at 900 with tight negative tracking.
 *
 * The single rule behind most of the others: when in doubt, take
 * something away. Almost every line here exists because a decoration was
 * removed and the screen got better.
 *
 * One file serves three surfaces — the owner's admin, the student
 * portal, and the public sales pages — so they cannot drift apart.
 */

/* ─────────────────────────────── the face ─────────────────────────── */

/*
 * Archivo, variable, self-hosted. Not Archivo Black: that ships a single
 * weight, and asking a 400-only family for 900 makes the browser
 * synthesize the bold, which smears glyphs sideways and shows at display
 * sizes. font-synthesis: none below means a future mismatch appears as
 * the wrong weight rather than a quietly distorted one.
 *
 * Self-hosted rather than pulled from Google: no third-party request on
 * every page, which matters for EU buyers, and it works offline.
 */
@font-face {
	font-family: 'Archivo';
	font-style: normal;
	font-weight: 400 900;
	font-stretch: 100%;
	font-display: swap;
	src: url('fonts/archivo-latin.woff2') format('woff2');
	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+2074, U+20AC, U+2122, U+2191,
		U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
	font-family: 'Archivo';
	font-style: normal;
	font-weight: 400 900;
	font-stretch: 100%;
	font-display: swap;
	src: url('fonts/archivo-latin-ext.woff2') format('woff2');
	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-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

/* ─────────────────────────────── tokens ──────────────────────────── */

.asfm {
	/* ink: warm-black, brown undertone. Every shadow is tinted with it. */
	--ink:             #1C1917;
	--ink-rgb:         28, 25, 23;
	--ink-d10:         #14100D;
	--ink-l10:         #2D282A;

	/* accent: terracotta */
	--accent:          #E8734A;
	--accent-rgb:      232, 115, 74;
	--accent-solid:    #C74619;
	--accent-text:     #C74619;
	--accent-on-panel: #A93D12;
	--accent-on-dark:  #F2672E;
	--accent-fill:     #F9ECE8;
	--accent-press:    #93350F;
	--accent-wash:     rgba(232, 115, 74, 0.05);
	--accent-wash-2:   rgba(232, 115, 74, 0.10);
	--accent-glow:     rgba(232, 115, 74, 0.12);
	--accent-edge:     rgba(232, 115, 74, 0.20);

	/* surfaces */
	--bg:    #FAFAF9;
	--panel: #EDE5DC;
	--card:  #FFFFFF;
	--bd:        rgba(28, 25, 23, 0.08);
	--bd-strong: rgba(28, 25, 23, 0.18);
	--panel-hover: #E2D8CC;
	--panel-press: #D8CCBE;

	/* text */
	--tx:               #1C1917;
	--tx-soft:          #57534E;
	--tx-mute:          #6A625C;
	--tx-soft-on-dark:  #D6D3D1;
	--tx-mute-on-dark:  #A8A29E;

	/* status: contrast-corrected, not the raw hues */
	--green:         #157A3B;
	--green-on-dark: #6EE7A8;
	--green-fill:    rgba(45, 138, 78, 0.12);
	--red:           #C0392B;
	--red-fill:      rgba(192, 57, 43, 0.10);
	--blue:          #1D4ED8;
	--blue-fill:     rgba(46, 134, 193, 0.12);
	--amber:         #F5A623;
	--amber-text:    #8A5C05;
	--amber-on-dark: #F0B429;
	--amber-fill:    rgba(230, 126, 34, 0.12);

	/* type — both roles are Archivo; they differ only in weight and tracking */
	--serif: 'Archivo', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
	--sans:  'Archivo', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;

	/* geometry: four radii, no others */
	--r-sm: 10px;
	--r: 14px;
	--r-lg: 20px;
	--r-pill: 999px;

	/* shadows: ink-tinted, used almost nowhere */
	--shadow:       0 1px 3px rgba(28,25,23,.04), 0 8px 24px rgba(28,25,23,.03);
	--shadow-btn:   0 4px 12px rgba(28,25,23,.12);
	--shadow-bar:   0 -4px 20px rgba(28,25,23,.06);
	--shadow-float: 0 3px 14px rgba(28,25,23,.28);
	--focus:        0 0 0 3px rgba(232,115,74,.18);

	--topbar-h: 52px;
	--mobilenav-h: 64px;
}

/* ───────────────────────────── the ground ────────────────────────── */

.asfm, .asfm * { box-sizing: border-box; }

.asfm {
	font-family: var(--sans);
	font-size: 14px;
	line-height: 1.5;
	color: var(--tx);
	background: var(--bg);
	-webkit-font-smoothing: antialiased;
	font-synthesis: none;
}

.asfm h1, .asfm h2, .asfm h3, .asfm h4 {
	font-family: var(--serif);
	font-weight: 900;
	margin: 0;
	letter-spacing: -.02em;
	color: var(--tx);
}

.asfm p { margin: 0 0 12px; }
.asfm p:last-child { margin-bottom: 0; }
.asfm a { color: var(--accent-text); text-decoration: none; }
.asfm a:hover { text-decoration: underline; }
.asfm button { font-family: inherit; }
.asfm code {
	font-family: ui-monospace, Menlo, Consolas, monospace;
	font-size: .92em; background: var(--panel); padding: 1px 5px; border-radius: 4px;
}

/* Every interactive thing gets a visible focus ring, not just inputs. */
.asfm :focus-visible {
	outline: 2px solid var(--accent-solid);
	outline-offset: 2px;
	border-radius: 4px;
}

/* Reduced motion genuinely stops motion. It does not shorten it. */
@media (prefers-reduced-motion: reduce) {
	.asfm *, .asfm *::before, .asfm *::after {
		animation-duration: .01ms !important;
		animation-iteration-count: 1 !important;
		transition-duration: .01ms !important;
	}
}

/* ─────────────────────────────── the shell ───────────────────────── */

.asfm-topbar {
	height: var(--topbar-h);
	position: sticky; top: 0; z-index: 200;
	display: flex; align-items: center; gap: 12px;
	padding: 0 20px;
	background: var(--ink);
	border-bottom: 1px solid var(--accent-glow);
}
.asfm .asfm-logo {
	font-family: var(--serif); font-size: 20px; font-weight: 900;
	color: #fff; letter-spacing: -.02em; text-decoration: none;
	white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.asfm .asfm-logo:hover { text-decoration: none; color: #fff; }
.asfm-burger {
	display: grid; place-items: center;
	width: 44px; height: 44px; margin-left: -10px;
	background: none; border: none; cursor: pointer;
	color: #fff; font-size: 18px; line-height: 1;
}
.asfm-topbar-right { margin-left: auto; display: flex; align-items: center; gap: 10px; }
.asfm .asfm-avatar {
	width: 32px; height: 32px; border-radius: 50%;
	display: grid; place-items: center;
	background: var(--accent-solid); color: #fff;
	font-family: var(--serif); font-size: 12px; font-weight: 900;
	flex-shrink: 0;
}

.asfm-app { display: flex; align-items: stretch; min-height: calc(100dvh - var(--topbar-h)); }

/* dvh, not vh: on iOS Safari 100vh is the height with browser chrome
   hidden, so the drawer is always taller than the space it has. */
.asfm-side {
	position: sticky; top: var(--topbar-h);
	height: calc(100dvh - var(--topbar-h));
	width: 0; padding: 0; overflow: hidden;
	background: var(--ink);
	transition: width .28s cubic-bezier(.4,0,.2,1), padding .28s;
	flex-shrink: 0;
	/* Closed means INERT, not clipped. Width zero alone leaves every link
	   in the layout, still hit-testable, still in the a11y tree. */
	visibility: hidden;
}
.asfm-side.open {
	width: 240px; padding: 20px 12px;
	box-shadow: 4px 0 32px rgba(0,0,0,.15);
	overflow-y: auto; overscroll-behavior: contain;
	visibility: visible;
}

.asfm-navlabel {
	font-size: 10px; font-weight: 700; letter-spacing: .15em; text-transform: uppercase;
	color: rgba(255,255,255,.6); padding: 0 12px; margin: 18px 0 6px;
}
.asfm-navsep { height: 1px; background: rgba(255,255,255,.1); margin: 14px 4px; }

.asfm .asfm-nav {
	display: flex; align-items: center; gap: 12px; width: 100%;
	padding: 10px 12px; min-height: 44px;
	background: none; border: none; border-radius: 8px;
	font-family: inherit; font-size: 14px; font-weight: 500;
	color: rgba(255,255,255,.75);
	cursor: pointer; text-align: left; white-space: nowrap; text-decoration: none;
}
.asfm .asfm-nav:hover { background: rgba(255,255,255,.08); color: #fff; text-decoration: none; }
.asfm .asfm-nav[aria-current="page"] {
	background: var(--accent-wash-2);
	color: var(--accent-on-dark);
	font-weight: 600;
}
/* Emoji glyph widths vary. A fixed-width tile is what keeps the text
   beside them starting at the same x — ragged left edges are the giveaway. */
.asfm-navicon { width: 24px; font-size: 18px; text-align: center; opacity: .8; flex-shrink: 0; }
.asfm-nav[aria-current="page"] .asfm-navicon { opacity: 1; }
.asfm-navbadge {
	margin-left: auto; background: var(--accent); color: var(--ink);
	font-size: 10px; font-weight: 700; padding: 3px 8px; border-radius: var(--r-pill);
}

.asfm-main { flex: 1; min-width: 0; padding: 36px 40px; max-width: 1200px; }

.asfm-pagetitle { font-size: 26px; font-weight: 900; letter-spacing: -.03em; margin-bottom: 4px; }
.asfm-pagesub { color: var(--tx-mute); margin-bottom: 24px; }

/* ─────────────────────────────── card ────────────────────────────── */

.asfm-card {
	background: var(--card); border: 1px solid var(--bd);
	border-radius: var(--r-sm);
	margin-bottom: 24px; overflow: hidden;
}
.asfm-cardtitle {
	font-family: var(--serif); font-size: 15px; font-weight: 900;
	padding: 18px 24px; border-bottom: 1px solid var(--bd);
	display: flex; align-items: center; justify-content: space-between; gap: 12px;
	flex-wrap: wrap;
}
.asfm-cardtitle > * { min-width: 0; }
.asfm-cardbody { padding: 24px; }

/* ─────────────────────── stat cards — the one ornament ───────────── */

.asfm-stats {
	display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
	gap: 14px; margin-bottom: 24px;
}
.asfm-stat {
	background: var(--card); border: 1px solid var(--bd);
	border-top: 3px solid var(--accent);
	border-radius: var(--r-sm); padding: 18px 20px 16px;
}
.asfm-stat.green { border-top-color: var(--green); }
.asfm-stat.red   { border-top-color: var(--red); }
.asfm-statlabel {
	font-size: 10px; font-weight: 700; letter-spacing: .12em; text-transform: uppercase;
	color: var(--tx-mute); line-height: 1;
}
.asfm-statvalue {
	font-family: var(--serif); font-size: 28px; font-weight: 900;
	letter-spacing: -.02em; line-height: 1.1; margin-top: 6px;
	font-variant-numeric: tabular-nums;
}
.asfm-statnote { font-size: 12px; color: var(--tx-mute); margin-top: 4px; }

/* ───────────────────── section — flat, no card, for lists ────────── */

.asfm-sec { margin: 0 0 34px; }
.asfm-sechead {
	display: flex; align-items: baseline; justify-content: space-between; gap: 12px;
	padding: 0 0 10px;
	border-bottom: 1.5px solid var(--ink);
	margin-bottom: 2px;
	flex-wrap: wrap;
}
.asfm-sechead h2 { font-size: 17px; }
.asfm-seccount { font-size: 13px; color: var(--tx-mute); font-variant-numeric: tabular-nums; }
.asfm-secact { margin: 14px 0; }

/* ─────────────────────────────── rows ────────────────────────────── */

.asfm .asfm-row {
	display: flex; align-items: center; gap: 14px;
	padding: 16px 0; border-bottom: 1px solid var(--bd);
	color: var(--ink);
	transition: background .12s ease;
}
.asfm-card .asfm-row { padding-left: 22px; padding-right: 22px; }
.asfm-row:last-child { border-bottom: none; }
/* A tint only. A row shifting 4px right on hover reads as the page twitching. */
.asfm .asfm-row:hover { background: var(--accent-wash); }
.asfm-row.flag { border-left: 3px solid var(--red); padding-left: 10px; }

.asfm-rowicon { width: 24px; font-size: 16px; text-align: center; flex-shrink: 0; line-height: 1; }
.asfm-rowmain { flex: 1; min-width: 0; }
.asfm .asfm-rowtitle {
	font-family: var(--serif); font-size: 16px; font-weight: 900; letter-spacing: -.01em;
	color: var(--ink); text-decoration: none; display: block;
	overflow-wrap: anywhere;
}
a.asfm-rowtitle:hover { color: var(--accent-text); text-decoration: none; }
.asfm-rowmeta {
	display: block; font-size: 12px; font-weight: 400; color: var(--tx-mute); margin-top: 3px;
}
.asfm-rowmeta.asfm-bad { color: var(--red); }
.asfm-rowside { flex-shrink: 0; display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.asfm-rowside form { display: inline-flex; margin: 0; }

/* ────────────────────────── the flow map ─────────────────────────── */
/* A sequence drawn as a shape rather than a list. Vertical, so it reads
   the same on a phone as on a desk, and built from boxes and borders
   rather than a canvas so every node is a real link. */
.asfm-map { display: flex; flex-direction: column; align-items: stretch; }

/* a.asfm-mapnode, not .asfm-mapnode: `.asfm a` is specificity (0,1,1)
   and beats a bare class, which is what turned every node terracotta.
   The same trap that painted the logo on the logo in 0.17.0. */
a.asfm-mapnode, .asfm-mapnode {
	position: relative; display: flex; align-items: center; gap: 9px;
	padding: 11px 13px; margin: 0 0 22px; border: 1px solid var(--line);
	border-radius: 10px; background: var(--bg); color: var(--tx);
	font-size: 14px; text-decoration: none; line-height: 1.35;
}
a.asfm-mapnode:hover { border-color: var(--accent); color: var(--tx); }

/* The line down to whatever comes next, drawn under the node so it is
   not clipped by the node's own rounded corner. */
.asfm-map .asfm-mapnode::after {
	content: ""; position: absolute; left: 22px; top: calc(100% + 1px);
	width: 2px; height: 21px; background: var(--line);
}
.asfm-map > .asfm-mapnode:last-child::after,
.asfm-maparm > .asfm-mapnode:last-child::after { display: none; }

.asfm-mapnum {
	flex: 0 0 auto; min-width: 20px; height: 20px; border-radius: 10px;
	background: var(--panel); color: var(--tx-soft);
	font-size: 11px; font-weight: 700; display: grid; place-items: center;
}
.asfm-maptext { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.asfm-mapnode.email     { border-left: 3px solid var(--accent); }
.asfm-mapnode.condition { border-left: 3px solid var(--amber); }
.asfm-mapnode.stop      { border-left: 3px solid var(--line); color: var(--tx-soft); }
.asfm-mapnode.loop      { color: var(--tx-soft); font-style: italic; }

/* A split: two arms side by side, stacked once there is no room. */
.asfm-mapsplit { display: flex; gap: 14px; align-items: flex-start; }
.asfm-maparm {
	flex: 1 1 0; min-width: 0; padding: 12px 0 0 12px;
	border-left: 1px solid var(--line); border-top: 1px solid var(--line);
	border-top-left-radius: 8px;
}
.asfm-maplabel {
	display: inline-block; margin: 0 0 8px; padding: 2px 8px;
	border-radius: 9px; background: var(--panel);
	font-size: 11px; font-weight: 700; color: var(--tx-soft);
	text-transform: uppercase; letter-spacing: .05em;
}
@media (max-width: 600px) {
	.asfm-mapsplit { flex-direction: column; gap: 0; }
}

/* ───────────────────────── filter rows ───────────────────────────── */
/* Three controls on one line on a desk, stacked on a phone. A filter
   that wraps mid-rule stops reading as one sentence. */
.asfm-filter {
	display: flex; gap: 8px; margin: 0 0 8px; flex-wrap: wrap;
}
.asfm-filter select, .asfm-filter input {
	flex: 1 1 150px; min-width: 0; margin: 0;
}
@media (max-width: 640px) {
	.asfm-filter { flex-direction: column; gap: 6px; }
}

/* ─────────────────────────── place tabs ──────────────────────────── */
/* One row, scrolled rather than wrapped: a tab row that wraps onto three
   lines on a phone stops reading as navigation and starts reading as a
   paragraph of links. */
.asfm-tabs {
	display: flex; gap: 2px; overflow-x: auto; scrollbar-width: none;
	border-bottom: 1px solid var(--line); margin: 0 0 22px;
	padding: 0 0 0 2px; -webkit-overflow-scrolling: touch;
}
.asfm-tabs::-webkit-scrollbar { display: none; }
.asfm-tabs a {
	flex: 0 0 auto; display: inline-flex; align-items: center; gap: 6px;
	padding: 11px 14px; font-size: 14px; font-weight: 600;
	color: var(--tx-soft); text-decoration: none; white-space: nowrap;
	border-bottom: 2px solid transparent; margin-bottom: -1px;
}
.asfm-tabs a:hover { color: var(--tx); }
.asfm-tabs a[aria-current="page"] {
	color: var(--tx); border-bottom-color: var(--accent);
}

/* ────────────────────────────── badges ───────────────────────────── */

/* Every state has a word. Colour reinforces it; it never replaces it. */
.asfm-badge {
	display: inline-flex; align-items: center;
	padding: 3px 8px; border-radius: 3px;
	font-size: 11px; font-weight: 600; letter-spacing: 0; white-space: nowrap;
	background: var(--panel); color: var(--tx-soft);
}
.asfm-badge.green { background: var(--green-fill); color: #0E5F2C; }
.asfm-badge.amber { background: var(--amber-fill); color: var(--amber-text); }
.asfm-badge.red   { background: var(--red-fill);   color: #A32B1E; }
.asfm-badge.blue  { background: var(--blue-fill);  color: var(--blue); }

/* ────────────────────────────── buttons ──────────────────────────── */

/*
 * Rectangles with 6px corners that do not move. Pill radius plus a lift
 * plus a coloured glow is three signals all saying "this is a button"
 * when one would do.
 */
.asfm .asfm-btn {
	display: inline-flex; align-items: center; justify-content: center; gap: 6px;
	padding: 10px 18px; min-height: 44px;
	border: none; border-radius: 6px;
	font-family: var(--sans); font-size: 13px; font-weight: 600;
	background: var(--panel); color: var(--ink);
	cursor: pointer; line-height: 1; white-space: nowrap; text-decoration: none;
	transition: background-color .12s ease, border-color .12s ease, color .12s ease;
}
.asfm .asfm-btn:hover  { background: var(--panel-hover); color: var(--ink); text-decoration: none; }
.asfm .asfm-btn:active { background: var(--panel-press); }

.asfm .asfm-btn.primary { background: var(--accent-solid); color: #fff; font-weight: 700; }
.asfm .asfm-btn.primary:hover { background: var(--accent-on-panel); color: #fff; }
.asfm .asfm-btn.primary:active { background: var(--accent-press); }

.asfm .asfm-btn.outline { background: var(--card); border: 1.5px solid var(--bd-strong); }
.asfm .asfm-btn.outline:hover { border-color: var(--accent-text); color: var(--accent-text);
                           background: var(--accent-wash); }

.asfm .asfm-btn.danger { background: #fff; border: 1.5px solid rgba(192,57,43,.3); color: var(--red); }
.asfm .asfm-btn.danger:hover { background: var(--red-fill); color: #A32B1E; }

/* Smaller visually. Still 44px tall — small never means un-tappable. */
.asfm-btn.sm { padding: 8px 14px; font-size: 12px; }

.asfm-btnrow { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; }
.asfm-btnrow form { display: inline-flex; margin: 0; }

/* ────────────────────────────── inputs ───────────────────────────── */

.asfm-field { display: block; margin-bottom: 16px; }
.asfm-label {
	display: block; font-size: 11px; font-weight: 700; letter-spacing: .07em;
	text-transform: uppercase; color: var(--tx-soft); margin-bottom: 6px;
}
.asfm-input, .asfm textarea, .asfm select,
.asfm input[type="text"], .asfm input[type="email"], .asfm input[type="url"],
.asfm input[type="password"], .asfm input[type="number"], .asfm input[type="search"],
.asfm input[type="time"], .asfm input[type="datetime-local"], .asfm input[type="date"] {
	font-family: var(--sans); font-size: 14px;
	padding: 10px 12px; min-height: 44px; width: 100%;
	background: #fff; border: 1.5px solid var(--bd); border-radius: var(--r-sm);
	color: var(--tx);
}
.asfm textarea { min-height: 96px; line-height: 1.55; }
.asfm input:focus, .asfm textarea:focus, .asfm select:focus {
	outline: none; border-color: var(--accent-text); box-shadow: var(--focus);
}
.asfm input::placeholder, .asfm textarea::placeholder { color: var(--tx-mute); }
.asfm-help { display: block; font-size: 12px; color: var(--tx-mute); margin-top: 5px; }

.asfm input[type="checkbox"], .asfm input[type="radio"] {
	width: 18px; height: 18px; min-height: 0; accent-color: var(--accent-solid);
	margin: 0 8px 0 0; vertical-align: -3px;
}
.asfm-check {
	display: flex; align-items: flex-start; gap: 2px;
	min-height: 44px; padding: 8px 0; cursor: pointer;
}
.asfm-check input { margin-top: 2px; flex-shrink: 0; }

/* One of two ways to do a thing, each with its own sentence. */
.asfm-pick {
	display: flex; align-items: flex-start; gap: 4px; cursor: pointer;
	padding: 12px 14px; border: 1px solid var(--bd); border-radius: 10px;
	margin-bottom: 8px; background: var(--card);
}
.asfm-pick:has(input:checked) { border-color: var(--accent-solid); }
.asfm-pick input { margin-top: 3px; flex-shrink: 0; }
.asfm-pick > span { display: block; }
.asfm-pick .asfm-help { margin-top: 2px; }

/* A page she wrote herself gets no layout from us at all. */
body.asfm-own { margin: 0; }

.asfm-inline { display: flex; gap: 10px; flex-wrap: wrap; align-items: flex-start; }
.asfm-inline > * { flex: 1 1 180px; }
.asfm-inline > .asfm-btn { flex: 0 0 auto; }
.asfm-narrow { max-width: 120px; }

/* ─────────────────────────────── tabs ───────────────────────────── */

.asfm-tabs {
	display: flex; align-items: stretch;
	border-bottom: 1.5px solid var(--ink);
	overflow-x: auto; overflow-y: hidden;
	-webkit-overflow-scrolling: touch; scrollbar-width: none;
	margin-bottom: 24px;
}
.asfm-tabs::-webkit-scrollbar { display: none; }
.asfm .asfm-tab {
	flex: none; display: inline-flex; align-items: center; gap: 7px;
	min-height: 44px; padding: 10px 16px 10px 0; margin-right: 20px;
	background: none; border: none; cursor: pointer;
	font-family: var(--serif); font-weight: 900; font-size: 15px;
	letter-spacing: -.01em; color: var(--tx-mute);
	border-bottom: 3px solid transparent; margin-bottom: -1.5px;
	white-space: nowrap; text-decoration: none;
	transition: color .12s ease, border-color .12s ease;
}
.asfm .asfm-tab:hover { color: var(--tx); text-decoration: none; }
.asfm .asfm-tab.on { color: var(--tx); border-bottom-color: var(--accent-solid); }
/* The count is never the same weight as the word, or the tab reads as two labels. */
.asfm-tabn {
	font-family: var(--sans); font-weight: 600; font-size: 12px;
	color: var(--tx-mute); font-variant-numeric: tabular-nums;
}
.asfm-tab.on .asfm-tabn { color: var(--accent-on-panel); }

/* ────────────────────────── empty state ──────────────────────────── */

/*
 * "No lessons yet" with nothing else on screen is a dead end. The empty
 * state carries the control that fills it. Hard rule, not a nicety.
 */
.asfm-empty { text-align: center; padding: 48px 24px; }
.asfm-emptyicon { font-size: 48px; line-height: 1; }
.asfm-emptytitle { font-family: var(--serif); font-size: 18px; font-weight: 900; margin-top: 12px; }
.asfm-emptysub { font-size: 13px; color: var(--tx-mute); margin-top: 6px; max-width: 46ch;
                 margin-left: auto; margin-right: auto; }
/* margin auto on the SIDES: this is a block-level flex container with a
   max-width, so it ignores the parent's text-align and sits hard left. */
.asfm-emptyact { margin: 18px auto 0; width: 100%; max-width: 460px;
                 display: flex; flex-direction: column; align-items: stretch;
                 gap: 8px; text-align: left; }

/* ───────────────────── the one dark panel per screen ─────────────── */

.asfm-hero {
	position: relative; overflow: hidden;
	background: var(--ink); border-radius: var(--r-lg);
	padding: 28px 32px; margin-bottom: 24px;
	color: #fff;
}
.asfm-hero h1, .asfm-hero h2 { color: #fff; }
.asfm-hero p { color: var(--tx-soft-on-dark); }
.asfm-hero a { color: var(--accent-on-dark); }
.asfm-hero strong { color: #fff; }
/* The radial accent glow. Most of the warmth in the whole product. */
.asfm-hero::before {
	content: ''; position: absolute; top: -40%; right: 0; width: 45%; height: 180%;
	background: radial-gradient(ellipse, var(--accent-glow) 0%, transparent 70%);
	pointer-events: none;
}
.asfm-hero > * { position: relative; }
/* Anything quiet that lands inside the dark panel has to be re-quietened
   against the dark, or it goes to grey-on-near-black and disappears. */
.asfm-hero .asfm-muted, .asfm-hero .asfm-soft { color: var(--tx-mute-on-dark); }
.asfm-hero .asfm-plan { color: var(--tx-soft-on-dark); }
.asfm-hero label { color: var(--tx-soft-on-dark); }

/* ──────────────────────────── notices ────────────────────────────── */

.asfm-note {
	border: 1px solid var(--bd); border-left: 3px solid var(--tx-mute);
	background: var(--card); border-radius: var(--r-sm);
	padding: 14px 18px; margin-bottom: 18px;
}
.asfm-note.good { border-left-color: var(--green); }
.asfm-note.warn { border-left-color: var(--amber); }
.asfm-note.bad  { border-left-color: var(--red); }
.asfm-note.act  { border-left-color: var(--accent-solid); }

/* A quiet panel for a block of settings or an explanation. */
.asfm-panel {
	background: var(--panel); border-radius: var(--r-sm);
	padding: 16px 18px; margin-bottom: 18px;
}
.asfm-panel a { color: var(--accent-on-panel); }

/* ─────────────────────────── progress ────────────────────────────── */

/* Always paired with the number in words nearby. A bar alone is decoration. */
.asfm-bar { display: block; height: 6px; border-radius: var(--r-pill); background: var(--panel); overflow: hidden; }
.asfm-barfill { display: block; height: 100%; border-radius: var(--r-pill); background: var(--accent-solid); }

/* ──────────────────────────── tables ─────────────────────────────── */

.asfm-tablewrap { overflow-x: auto; }
.asfm-t { width: 100%; border-collapse: collapse; font-size: 13px; }
/* Sentence case. A table already tells you it is a table; it does not
   also need the shouting label used nineteen other places. */
.asfm-t th {
	text-align: left; font-size: 12px; font-weight: 600; letter-spacing: 0;
	text-transform: none; color: var(--tx-mute);
	padding: 10px 16px 10px 0; border-bottom: 1px solid var(--bd); white-space: nowrap;
}
.asfm-t td { padding: 14px 16px 14px 0; border-bottom: 1px solid var(--bd); vertical-align: top; }
.asfm-t th:last-child, .asfm-t td:last-child { padding-right: 0; }
.asfm-t tr:last-child td { border-bottom: none; }
.asfm-t .num { text-align: right; font-variant-numeric: tabular-nums; }

/* ─────────────────────── message bubbles ─────────────────────────── */

.asfm-thread { display: flex; flex-direction: column; gap: 4px; margin-bottom: 20px; }
.asfm-bubble {
	max-width: min(78%, 480px);
	padding: 9px 14px; border-radius: 20px;
	background: var(--panel); color: var(--tx);
	font-size: 15px; line-height: 1.4; overflow-wrap: anywhere; white-space: pre-wrap;
	align-self: flex-start;
}
.asfm-bubble.mine { background: var(--accent-solid); color: #fff; align-self: flex-end; }
.asfm-bubble.note { background: var(--amber-fill); color: var(--tx); align-self: flex-end;
                    border: 1px dashed rgba(230,126,34,.5); }
.asfm-bubble.last { border-bottom-left-radius: 6px; }
.asfm-bubble.mine.last { border-bottom-left-radius: 20px; border-bottom-right-radius: 6px; }
.asfm-bubblemeta { font-size: 11px; color: var(--tx-mute); margin: 6px 0 2px; }
.asfm-bubblemeta.mine { text-align: right; }

/* ────────────────────────── odds and ends ────────────────────────── */

/* Said to a screen reader, not shown. WordPress ships this class and we
   have hidden its stylesheet, so it has to exist here or the label text
   turns up on screen next to the control it was describing. */
.asfm .screen-reader-text, .asfm-sr {
	position: absolute !important; width: 1px; height: 1px;
	margin: -1px; padding: 0; border: 0; overflow: hidden;
	clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap;
}

.asfm-muted { color: var(--tx-mute); }
.asfm-soft  { color: var(--tx-soft); }
.asfm-small { font-size: 12px; }
.asfm-prose { max-width: 64ch; }
.asfm-num   { font-variant-numeric: tabular-nums; }
.asfm [hidden] { display: none !important; }
.asfm hr { border: none; border-top: 1px solid var(--bd); margin: 26px 0; }

/* ─────────────────────────────── mobile ──────────────────────────── */

@media (max-width: 1024px) {
	.asfm-side.open { width: 220px; }
	.asfm-main { padding: 24px 20px; }
}

@media (max-width: 782px) {
	.asfm-topbar { padding: 0 12px; }
	.asfm-logo { font-size: 16px; }

	/* The drawer becomes a fixed overlay, capped so it never swallows the screen. */
	.asfm-side {
		position: fixed; left: 0; top: var(--topbar-h); z-index: 500;
		height: calc(100dvh - var(--topbar-h));
	}
	.asfm-side.open { width: min(280px, 85vw); }

	.asfm-mobilenav {
		display: flex; position: fixed; bottom: 0; left: 0; right: 0; z-index: 600;
		height: calc(var(--mobilenav-h) + env(safe-area-inset-bottom, 0px));
		padding-bottom: env(safe-area-inset-bottom, 0px);
		background: rgba(255,255,255,.96); backdrop-filter: blur(12px);
		border-top: 1.5px solid var(--bd);
		box-shadow: var(--shadow-bar);
	}
	.asfm-mobilenav a {
		flex: 1; display: flex; flex-direction: column; align-items: center;
		justify-content: center; gap: 3px; min-height: 44px;
		text-decoration: none; color: var(--tx-mute); font-size: 10px; font-weight: 600;
	}
	.asfm-mobilenav a[aria-current="page"] { color: var(--accent-text); }
	.asfm-mnicon { font-size: 20px; line-height: 1; }

	/* iOS zooms any input under 16px on focus. */
	.asfm input, .asfm select, .asfm textarea { font-size: 16px; min-height: 48px; }

	.asfm-hero { padding: 22px 20px; }
	.asfm-cardbody, .asfm-cardtitle { padding-left: 18px; padding-right: 18px; }
	.asfm-card .asfm-row { padding-left: 18px; padding-right: 18px; }
}

.asfm-mobilenav { display: none; }

@media (max-width: 480px) {
	.asfm-main { padding: 16px 14px calc(var(--mobilenav-h) + 24px); }
	.asfm-stats { grid-template-columns: 1fr; }
	.asfm-pagetitle { font-size: 18px; }
	.asfm-hero { border-radius: var(--r); }
}

@media (max-width: 390px) {
	.asfm-main { padding: 14px 12px calc(var(--mobilenav-h) + 24px); }
	.asfm-btnrow .asfm-btn { width: 100%; }
	.asfm-btnrow form { display: flex; width: 100%; }
	.asfm-btnrow form .asfm-btn { width: 100%; }
}

/* Touch devices: nothing lifts. */
@media (hover: none) and (pointer: coarse) {
	.asfm-btn:hover, .asfm-row:hover { transform: none; }
}

/* ─────────────────────────── the student portal ───────────────────── */

/*
 * The portal is the same system with the rail taken out. A student has
 * four places to be, not twenty, so the navigation is four links in the
 * topbar on a desk and the bottom bar on a phone — and nothing at all
 * while they are signed out.
 *
 * One column, capped at 720px. A lesson is read, and reading has a width
 * past which the eye loses the start of the next line.
 */
.asfm-portal {
	width: 100%; max-width: 720px; margin: 0 auto;
	padding: 30px 24px 80px;
	flex: 1;
}
/* The column, the footer and the bar, stacked — so on a short page the
   business name sits at the bottom of the screen rather than halfway up
   it with a rule under nothing. */
body.asfm { display: flex; flex-direction: column; min-height: 100dvh; }

/* A title, then air, then the first list. Without this the section rule
   lands right under the name and reads as an underline on it, and the
   dark panel looks welded to the headline. */
.asfm-portal .asfm-sec { margin-top: 26px; }
.asfm-portal .asfm-sec:first-of-type { margin-top: 22px; }
.asfm-portaltitle + .asfm-hero,
.asfm-portaltitle + .asfm-panel,
.asfm-portaltitle + .asfm-card { margin-top: 20px; }
.asfm-toplinks { display: flex; gap: 2px; }
.asfm .asfm-toplink {
	display: inline-flex; align-items: center; gap: 6px;
	min-height: 36px; padding: 8px 13px; border-radius: var(--r-pill);
	font-size: 13px; font-weight: 600;
	color: rgba(255,255,255,.75); text-decoration: none; white-space: nowrap;
}
.asfm .asfm-toplink:hover { background: rgba(255,255,255,.08); color: #fff; text-decoration: none; }
.asfm .asfm-toplink[aria-current="page"] { background: var(--accent-edge); color: #fff; }

.asfm-crumb { margin: 0 0 16px; }
.asfm .asfm-crumb a {
	display: inline-flex; align-items: center; gap: 6px; min-height: 44px;
	font-size: 13px; font-weight: 600; color: var(--tx-mute);
}
.asfm .asfm-crumb a:hover { color: var(--accent-text); text-decoration: none; }

/* The student's own page title. Bigger than the owner's, because there
   is one thing on this screen and it is this. */
.asfm-portaltitle {
	font-family: var(--serif); font-weight: 900; font-size: 34px; line-height: 1.06;
	letter-spacing: -.03em; margin: 0 0 12px;
}
.asfm-lede { font-size: 16px; line-height: 1.55; color: var(--tx-soft); margin: 0 0 20px; max-width: 54ch; }

/* Reading copy: longer measure, looser leading, full ink. A lesson is
   not interface text. */
.asfm-body { font-size: 17px; line-height: 1.7; color: var(--tx); max-width: 64ch; }
.asfm-body p { margin: 0 0 18px; }
.asfm-body h2, .asfm-body h3 { font-size: 19px; margin: 28px 0 10px; letter-spacing: -.02em; }
.asfm-body ul, .asfm-body ol { margin: 0 0 18px; padding-left: 22px; }
.asfm-body li { margin-bottom: 8px; }
.asfm-body img { max-width: 100%; height: auto; border-radius: var(--r-sm); }

.asfm-video {
	width: 100%; display: block; margin: 0 0 20px;
	background: var(--ink); border-radius: var(--r);
}

/* Back and forward through a course, side by side and equal — neither is
   the primary one, which is the point. */
.asfm-pager {
	display: flex; gap: 10px; margin-top: 30px; padding-top: 22px;
	border-top: 1px solid var(--bd);
}
.asfm-pager .asfm-btn { flex: 1; }

/* A lesson that is not theirs yet still shows, greyed in words rather
   than in opacity: the row says "Locked" out loud. */
.asfm-row.shut .asfm-rowtitle { color: var(--tx-mute); }

.asfm-portalfoot {
	width: 100%; max-width: 720px; margin: 0 auto; padding: 26px 24px 40px;
	border-top: 1px solid var(--bd);
	font-size: 12px; color: var(--tx-mute);
}

/* A date between bubbles, so a thread that spans months reads as one. */
.asfm-day { text-align: center; margin: 22px 0 10px; }
.asfm-day span {
	font-size: 11px; font-weight: 600; letter-spacing: .1em; text-transform: uppercase;
	color: var(--tx-mute);
}

/* The box you write in. Round, because every message box people already
   use is round, and this is not the place to be original. */
.asfm-composer {
	display: flex; gap: 9px; align-items: flex-end;
	margin-top: 24px; padding-top: 18px; border-top: 1px solid var(--bd);
}
.asfm .asfm-composer textarea {
	flex: 1; min-height: 44px; max-height: 160px; resize: none;
	padding: 12px 16px; border-radius: 22px; line-height: 1.45;
}
/* [type="submit"] spelled out, because the compatibility layer further
   down matches button[type="submit"] and would otherwise win on source
   order and paint this beige. */
.asfm .asfm-composer button[type="submit"] {
	flex: none; width: 44px; height: 44px; min-height: 44px; padding: 0;
	border: none; border-radius: 50%; cursor: pointer;
	background: var(--accent-solid); color: #fff; font-size: 18px;
	white-space: nowrap;
}
.asfm .asfm-composer button[type="submit"]:hover { background: var(--accent-on-panel); }

/* A quiz question. No timer, no red, no box that looks like an exam
   paper — the number is small and grey and the question is the loud part. */
.asfm-q { padding: 26px 0; border-bottom: 1px solid var(--bd); }
.asfm-q:last-of-type { border-bottom: none; }
.asfm-qn {
	font-size: 11px; font-weight: 600; letter-spacing: .1em;
	color: var(--tx-mute); margin-bottom: 8px; font-variant-numeric: tabular-nums;
}
.asfm-qbody { font-size: 18px; line-height: 1.4; font-weight: 600; margin: 0 0 16px; }
.asfm-opt {
	display: flex; gap: 12px; align-items: flex-start;
	padding: 12px 0; min-height: 44px; cursor: pointer;
	border-bottom: 1px solid var(--bd);
}
.asfm-opt:last-of-type { border-bottom: none; }
.asfm .asfm-opt input { margin: 4px 0 0; flex: none; width: 18px; height: 18px; min-height: 0;
                        accent-color: var(--accent-solid); }
.asfm-opt span { font-size: 16px; line-height: 1.45; }

/* A post in a space. No avatar, no card, no like-count in a pill — the
   words are the thing and everything else is a line of grey underneath. */
.asfm-post { padding: 22px 0; border-bottom: 1px solid var(--bd); }
.asfm-post:last-of-type { border-bottom: none; }
.asfm-posttitle { font-size: 19px; margin: 0 0 6px; line-height: 1.25; letter-spacing: -.02em; }
.asfm-postbody { margin: 0; color: var(--tx); line-height: 1.6; white-space: pre-wrap;
                 overflow-wrap: anywhere; }
.asfm-postmeta { font-size: 12px; color: var(--tx-mute); margin-top: 10px; }

/* Signed out, there is nowhere to navigate to, so the column centres and
   the form sits at a width a thumb can fill. */
.asfm-portal.alone { max-width: 460px; padding-top: 56px; }

@media (max-width: 782px) {
	.asfm-toplinks { display: none; }
	.asfm-portaltitle { font-size: 28px; }
}
@media (max-width: 480px) {
	.asfm-portal { padding: 20px 16px calc(var(--mobilenav-h) + 32px); }
	.asfm-portal.alone { padding-top: 34px; }
	.asfm-portalfoot { padding: 22px 16px calc(var(--mobilenav-h) + 24px); }
	.asfm-body { font-size: 16px; }
}

/* The portal's bottom bar is not the admin's — it is on at every width
   below the point the topbar links disappear, signed in only. */
@media (max-width: 782px) {
	.asfm-portal-has-nav .asfm-mobilenav { display: flex; }
}

/* ───────────────────────── the public sales page ──────────────────── */

/*
 * The one surface a stranger sees. Same tokens, same face, same buttons
 * as everything behind the sign-in — a page that sells in one voice and
 * then delivers in another is the thing that makes a shop feel bought
 * rather than built.
 *
 * Wider measure than an app screen and looser leading, because this is
 * read straight through rather than scanned.
 */
.asfm-sales {
	width: 100%; max-width: 820px; margin: 0 auto;
	padding: 0 24px 72px; flex: 1;
	font-size: 17px; line-height: 1.62;
}

/*
 * The measure stays narrow for reading even though the page got wider.
 * A picture wants the width; a paragraph does not, and 90 characters a
 * line is where prose stops being comfortable.
 */
.asfm-salessec p,
.asfm-salessec ul,
.asfm-salessec ol { max-width: 64ch; }
/*
 * The list of what is inside was the one block that ran the full width
 * while every paragraph above it stopped two thirds of the way across.
 * On a desk that reads as a page that lost its margin halfway down, so
 * it takes the same measure as the prose it sits between.
 */
.asfm-salessec .asfm-salesinside { max-width: 64ch; }

.asfm-salestop { padding: 34px 0 30px; border-bottom: 1px solid var(--bd-strong); }
.asfm-salestitle {
	font-family: var(--serif); font-weight: 900; font-size: 38px; line-height: 1.04;
	letter-spacing: -.03em; margin: 0;
}
.asfm-salesub { font-size: 19px; line-height: 1.45; color: var(--tx-soft); margin: 14px 0 0; }

.asfm-salessec { padding: 30px 0; border-bottom: 1px solid var(--bd); }
.asfm-salessec:last-of-type { border-bottom: none; }
/*
 * A section heading was 20px against 18px of body. Two pixels is not a
 * hierarchy, it is a bold paragraph, and the whole page read as one
 * undifferentiated column because of it.
 */
.asfm-salessec h2 {
	font-family: var(--serif); font-weight: 900;
	font-size: 27px; line-height: 1.15; letter-spacing: -.02em;
	margin: 0 0 16px;
}
.asfm-salessec p { margin: 0 0 16px; }
.asfm-salessec .asfm-btn { margin-top: 18px; }

/* ─── the hero, with the thing itself beside it ─── */

.asfm-salestop-in { display: grid; gap: 22px; align-items: start; }
.asfm-salestop-in > * { min-width: 0; }
.asfm-salestop-buy { margin: 0; }
.asfm-salestop-pic img {
	display: block; width: 100%; height: auto; border-radius: var(--r-sm);
	box-shadow: 0 1px 2px rgba(0,0,0,.06), 0 12px 34px rgba(0,0,0,.10);
}

/* ─── a picture on its own ─── */

.asfm-salespic { margin: 0; padding: 30px 0; border-bottom: 1px solid var(--bd); }
.asfm-salespic img { display: block; width: 100%; height: auto; border-radius: var(--r-sm); }
.asfm-salespic.inline img { max-width: 420px; }
.asfm-salespic figcaption {
	margin-top: 10px; font-size: 14px; color: var(--tx-mute); max-width: 62ch;
}
/* Out past the measure, because a picture that fills the column is the
   point of choosing full. */
.asfm-salespic.full { margin-left: -24px; margin-right: -24px; }
.asfm-salespic.full img { border-radius: 0; }
.asfm-salespic.full figcaption { padding: 0 24px; }

/* ─── a picture and some writing ─── */

.asfm-salessplit { display: grid; gap: 24px; align-items: center; }
.asfm-salessplit-pic img {
	display: block; width: 100%; height: auto; border-radius: var(--r-sm);
	box-shadow: 0 1px 2px rgba(0,0,0,.06), 0 10px 28px rgba(0,0,0,.09);
}
.asfm-salessplit-words p:last-child { margin-bottom: 0; }

/* ─── what is inside ─── */

/*
 * Two lines per item, not two columns. The old shape borrowed the
 * admin's table row, whose side never shrinks, so a sentence in it
 * pushed every row to a different split and the list came out ragged.
 */
.asfm-salesinside { list-style: none; margin: 0; padding: 0; }
.asfm-salesinside li {
	padding: 15px 0 15px 26px; border-bottom: 1px solid var(--bd); position: relative;
}
.asfm-salesinside li:last-child { border-bottom: none; }
.asfm-salesinside li::before {
	content: ""; position: absolute; left: 2px; top: 25px;
	width: 7px; height: 7px; border-radius: 50%; background: var(--accent-solid);
}
.asfm-salesinside-t {
	display: block; font-family: var(--serif); font-weight: 900;
	font-size: 18px; line-height: 1.3; letter-spacing: -.01em; color: var(--ink);
}
.asfm-salesinside-n {
	display: block; margin-top: 4px; font-size: 15.5px; line-height: 1.5;
	color: var(--tx-soft); max-width: 58ch;
}

/* ─── a video, and anything she wrote herself ─── */

.asfm-salesfilm { border-radius: var(--r-sm); overflow: hidden; }
.asfm-salesown img,
.asfm-salesown iframe,
.asfm-salesown video { max-width: 100%; }

/* The figure. The single largest thing on the page, which is honest:
   it is the question everybody scrolled down to answer. */
.asfm-priceline { display: flex; align-items: baseline; gap: 12px; flex-wrap: wrap; }
.asfm-amount {
	font-family: var(--serif); font-weight: 900; font-size: 44px; line-height: 1;
	letter-spacing: -.03em;
}
.asfm-was { font-size: 20px; color: var(--tx-mute); text-decoration: line-through; }
.asfm-alsothe { flex: 1 1 100%; font-size: 15px; color: var(--tx-mute); }

/* Somebody's actual words, on a card, with their name under it. */
.asfm-quote {
	border: 1px solid var(--bd); border-radius: var(--r-sm);
	background: var(--card); padding: 18px 20px; margin: 0 0 12px;
}
.asfm-quote p { font-size: 16px; margin: 0 0 10px; }
.asfm-quote cite { font-style: normal; font-size: 12px; font-weight: 600; color: var(--tx-mute); }

.asfm-faq { border-bottom: 1px solid var(--bd); padding: 14px 0; }
.asfm-faq:last-of-type { border-bottom: none; }
.asfm-faq > summary {
	cursor: pointer; list-style: none; font-size: 16px; font-weight: 600;
	display: flex; justify-content: space-between; gap: 14px; min-height: 44px;
	align-items: center;
}
.asfm-faq > summary::-webkit-details-marker { display: none; }
.asfm-faq > summary::after { content: "+"; color: var(--accent-solid); font-size: 22px; line-height: 1; }
.asfm-faq[open] > summary::after { content: "\2013"; }
.asfm-faq p { margin: 6px 0 10px; color: var(--tx-soft); font-size: 16px; }

.asfm-plan {
	display: flex; gap: 10px; align-items: flex-start;
	font-size: 15px; color: var(--tx-soft); padding: 6px 0; cursor: pointer;
}
.asfm .asfm-plan input { margin: 3px 0 0; flex: none; accent-color: var(--accent-solid); }

/* One buy form, used in three places on the page, always the same shape:
   the address, then the button, stacked, both full width on a phone. */
.asfm-buy { display: grid; gap: 10px; margin-top: 18px; }
.asfm-buy .asfm-btn { width: 100%; }

.asfm-salesfoot {
	width: 100%; max-width: 660px; margin: 0 auto;
	padding: 22px 24px 40px; font-size: 12px; color: var(--tx-mute);
}

@media (min-width: 680px) {
	.asfm-sales { font-size: 18px; }
	.asfm-salestitle { font-size: 48px; }
	.asfm-amount { font-size: 52px; }
	.asfm-buy { justify-items: start; max-width: 400px; }

	/* Side by side once there is room for both. Below this they stack,
	   picture first, which is the right order on a phone. */
	/* The picture takes a column of its own and stands beside all of it;
	   everything else keeps flowing down the first. */
	.asfm-salestop-in.haspic { grid-template-columns: 1.1fr .9fr; gap: 16px 40px; align-items: center; }
	.asfm-salestop-in.haspic > .asfm-salestop-pic { grid-column: 2; grid-row: 1 / span 3; align-self: center; }
	.asfm-salestop-in.haspic > .asfm-salestitle,
	.asfm-salestop-in.haspic > .asfm-salesub,
	.asfm-salestop-in.haspic > .asfm-salestop-buy { grid-column: 1; }
	.asfm-salessplit { grid-template-columns: 1fr 1fr; gap: 34px; }
	.asfm-salessplit.flip .asfm-salessplit-pic { order: 2; }
	.asfm-salesinside li { padding-left: 30px; }
}
@media (min-width: 900px) {
	.asfm-salespic.full { margin-left: -60px; margin-right: -60px; }
	.asfm-salespic.full figcaption { padding: 0 60px; }

	/*
	 * A hero with no picture used to be a title, a promise and a form
	 * stacked down the left of a page twice their width, with the whole
	 * right half of the first screen empty. Nothing was broken; it just
	 * looked like a document rather than a page somebody designed.
	 *
	 * So the form goes beside the promise instead of under it. The thing
	 * somebody has to do to get this is then at eye level rather than
	 * below the fold of a wide screen, and the width is used either way:
	 * with a picture it holds the picture, without one it holds the form.
	 */
	.asfm-salestop-in:not(.haspic) {
		grid-template-columns: 1.15fr .85fr;
		gap: 10px 48px;
		align-items: start;
	}
	.asfm-salestop-in:not(.haspic) > .asfm-salestitle,
	.asfm-salestop-in:not(.haspic) > .asfm-salesub { grid-column: 1; }
	.asfm-salestop-in:not(.haspic) > .asfm-salestop-buy {
		grid-column: 2; grid-row: 1 / span 2; align-self: center;
	}
	.asfm-salestop-in:not(.haspic) > .asfm-salestop-buy .asfm-priceline { margin-top: 0 !important; }
}
@media (max-width: 480px) {
	.asfm-sales { padding: 0 16px 56px; }
	.asfm-salestitle { font-size: 30px; }
	.asfm-salessec h2 { font-size: 23px; }
	.asfm-amount { font-size: 36px; }
	.asfm-salesfoot { padding: 20px 16px 32px; }
	.asfm-salespic.full { margin-left: -16px; margin-right: -16px; }
	.asfm-salespic.full figcaption { padding: 0 16px; }
}

/* ───────────── one card, centred, nothing else on the page ────────── */

/*
 * Two screens work this way: the moment after paying, and the public
 * certificate check. Both are a single statement somebody reads once and
 * leaves, so both are one card in the middle of an empty page with no
 * navigation to wander off into.
 */
/* body.asfm is a flex column for the portal, so this has to out-specify
   it rather than merely follow it. */
body.asfm.asfm-alone {
	min-height: 100dvh; display: grid; place-items: center; padding: 24px;
}
.asfm-alonecard {
	width: 100%; max-width: 520px;
	background: var(--card); border: 1px solid var(--bd); border-radius: var(--r-lg);
	padding: 34px 28px 30px;
}
.asfm-alonecard h1 {
	font-size: 30px; line-height: 1.06; letter-spacing: -.03em; margin: 0 0 12px;
}
.asfm-alonecard p { color: var(--tx-soft); margin: 0 0 14px; }
.asfm-alonecard p strong { color: var(--tx); font-weight: 700; }
.asfm-alonemark { font-size: 12px; font-weight: 600; color: var(--tx-mute); margin-bottom: 18px; }
.asfm-serial {
	font-family: ui-monospace, Menlo, Consolas, monospace; font-size: 13px;
	letter-spacing: .06em; color: var(--tx-mute);
}

/* Three dots, because a spinner that never stops is a lie and a bar that
   fills to 90% and waits is a worse one. */
.asfm-dots { display: flex; gap: 9px; align-items: center; color: var(--tx-mute);
             font-size: 15px; margin-top: 20px; }
.asfm-dots i {
	display: inline-block; width: 6px; height: 6px; border-radius: 50%;
	background: var(--bd); margin-right: 4px; animation: asfm-blink 1.3s infinite;
}
.asfm-dots i:nth-child(2) { animation-delay: .18s; }
.asfm-dots i:nth-child(3) { animation-delay: .36s; }
@keyframes asfm-blink {
	0%, 60%, 100% { background: var(--bd-strong); }
	30%           { background: var(--accent-solid); }
}

@media (min-width: 600px) {
	.asfm-alonecard { padding: 42px 38px 36px; }
	.asfm-alonecard h1 { font-size: 36px; }
}
@media (max-width: 480px) {
	body.asfm.asfm-alone { padding: 16px; }
	.asfm-alonecard { padding: 26px 20px 24px; border-radius: var(--r); }
	.asfm-alonecard h1 { font-size: 26px; }
}

/* ───────────────── taking over the WordPress admin ───────────────── */

/*
 * On an ASFM screen the plugin owns the whole window. WordPress's grey
 * chrome, its menu and its admin bar all go, because two navigations on
 * one screen is one too many and the grey is the main reason the admin
 * did not feel like her product.
 *
 * Scoped to body.asfm-takeover, which is only ever set on these pages.
 */
body.asfm-takeover { background: var(--bg, #FAFAF9); }
body.asfm-takeover #adminmenumain,
body.asfm-takeover #wpadminbar,
body.asfm-takeover #wpfooter,
body.asfm-takeover #screen-meta,
body.asfm-takeover #screen-meta-links { display: none !important; }
body.asfm-takeover #wpcontent { margin-left: 0 !important; padding-left: 0 !important; }
body.asfm-takeover #wpbody-content { padding-bottom: 0 !important; }
body.asfm-takeover #wpbody { padding-top: 0 !important; }

/*
 * The grey stripe along the top.
 *
 * WordPress pads the HTML element down — 32px, 46 on a phone — to leave
 * room for the admin bar, and it hangs that padding off html.wp-toolbar.
 * Two rules used to sit here trying to undo it from the body, and both
 * were dead: `body.asfm-takeover html` can never match, because html is
 * not inside body, and body never had the margin in the first place. So
 * the stripe was on every admin screen in the plugin and no harness ever
 * saw it, because no harness rendered inside WordPress's own page.
 *
 * The real fix is Chrome::no_admin_bar(), which stops WordPress writing
 * the class at all. This stays as a safety net for the case where
 * something else switches the bar back on.
 */
html:has( body.asfm-takeover ) { padding-top: 0 !important; }

/* Other plugins' notices still land here. Keep them readable and out of the way. */
body.asfm-takeover .notice,
body.asfm-takeover .updated,
body.asfm-takeover .error {
	margin: 0 0 14px !important;
	border-radius: 10px; border-left-width: 3px;
	font-family: 'Archivo', -apple-system, sans-serif; font-size: 13px;
}

/* ────────────── WordPress markup, wearing the system ─────────────── */

/*
 * The screens were built with WordPress's own admin classes. Rather than
 * rewrite every printf in nine files — which is how typos get into
 * working screens — the classes are mapped onto the system here, once.
 *
 * New markup uses the real component classes above. This section is for
 * what already exists, and it means every screen inherits the design in
 * one pass rather than twenty.
 */

.asfm .wrap { margin: 0; max-width: 100%; }
.asfm .wrap > h1 {
	font-size: 26px; font-weight: 900; letter-spacing: -.03em;
	margin: 0 0 20px; padding: 0;
}
.asfm h2 { font-size: 17px; margin: 30px 0 12px; }
.asfm h2:first-child { margin-top: 0; }

/* Buttons */
/*
 * :not(.asfm-btn) on every one of these. Without it a
 * <button type="submit" class="asfm-btn"> is caught by the compatibility
 * layer as well as by the component, and since an attribute selector
 * outranks a bare class, the compatibility layer's width:auto wins and
 * the button silently refuses to go full width on a phone. Any selector
 * added here that can match a component needs the same guard.
 */
.asfm .button,
.asfm button[type="submit"]:not(.asfm-btn),
.asfm input[type="submit"]:not(.asfm-btn) {
	display: inline-flex; align-items: center; justify-content: center; gap: 6px;
	padding: 10px 18px; min-height: 44px;
	border: none; border-radius: 6px;
	font-family: var(--sans); font-size: 13px; font-weight: 600;
	background: var(--panel); color: var(--ink);
	cursor: pointer; line-height: 1; white-space: nowrap; text-decoration: none;
	transition: background-color .12s ease, color .12s ease;
	box-shadow: none; text-shadow: none; width: auto; height: auto;
}
.asfm .button:hover { background: var(--panel-hover); color: var(--ink); border: none; }
.asfm .button:active { background: var(--panel-press); }
.asfm .button-primary,
.asfm button[type="submit"].button-primary:not(.asfm-btn),
.asfm input[type="submit"].button-primary:not(.asfm-btn) {
	background: var(--accent-solid); color: #fff; font-weight: 700; border: none;
}
.asfm .button-primary:hover { background: var(--accent-on-panel); color: #fff; }
.asfm .button-small { padding: 8px 14px; font-size: 12px; min-height: 44px; }
.asfm .button-delete, .asfm .button-link-delete {
	background: #fff; border: 1.5px solid rgba(192,57,43,.3); color: var(--red);
}
.asfm .button-delete:hover { background: var(--red-fill); color: #A32B1E; }
.asfm .page-title-action { display: none; }
.asfm p.submit { margin: 16px 0 0; padding: 0; }

/* Tables — WordPress's widefat, wearing ours */
.asfm .widefat {
	width: 100%; border-collapse: collapse; border: none;
	background: none; box-shadow: none; font-size: 13px;
	margin-bottom: 8px;
}
.asfm .widefat thead th, .asfm .widefat th {
	text-align: left; font-size: 12px; font-weight: 600; letter-spacing: 0;
	text-transform: none; color: var(--tx-mute); background: none;
	padding: 10px 16px 10px 0; border-bottom: 1px solid var(--bd); white-space: nowrap;
}
.asfm .widefat td {
	padding: 15px 16px 15px 0; border-bottom: 1px solid var(--bd);
	vertical-align: top; color: var(--tx); font-size: 13px; line-height: 1.5;
}
.asfm .widefat th:last-child, .asfm .widefat td:last-child { padding-right: 0; }
.asfm .widefat tr:last-child td { border-bottom: none; }
/* No zebra. Striping every other row is decoration doing the job a rule
   already does, and it makes a long list read as a spreadsheet. */
.asfm .striped > tbody > :nth-child(odd) { background: none; }
.asfm .widefat tbody tr:hover { background: var(--accent-wash); }
.asfm .widefat td strong,
.asfm .widefat td a strong {
	font-family: var(--serif); font-size: 15px; font-weight: 900; letter-spacing: -.01em;
}
.asfm .widefat td a { color: var(--ink); }
.asfm .widefat td a:hover { color: var(--accent-text); }

/* Forms — WordPress's form-table, wearing ours */
.asfm .form-table { width: 100%; border-collapse: collapse; margin: 0 0 8px; }
.asfm .form-table th {
	text-align: left; padding: 16px 24px 16px 0; width: 220px; vertical-align: top;
	font-size: 11px; font-weight: 700; letter-spacing: .07em; text-transform: uppercase;
	color: var(--tx-soft); line-height: 1.6;
}
.asfm .form-table td { padding: 12px 0 16px; vertical-align: top; }
.asfm .form-table tr { border-bottom: 1px solid var(--bd); }
.asfm .form-table tr:last-child { border-bottom: none; }
.asfm .regular-text { max-width: 340px; }
.asfm .large-text { width: 100%; }
.asfm .description, .asfm .form-table p.description {
	display: block; font-size: 12px; color: var(--tx-mute); margin: 6px 0 0;
	font-style: normal;
}

/* Notices */
.asfm .notice, .asfm .updated, .asfm .error {
	background: var(--card); border: 1px solid var(--bd);
	border-left: 3px solid var(--tx-mute);
	border-radius: var(--r-sm); padding: 13px 18px; margin: 0 0 18px;
	box-shadow: none;
}
.asfm .notice p, .asfm .updated p, .asfm .error p { margin: 0; padding: 0; font-size: 13px; }
.asfm .notice-success, .asfm .updated { border-left-color: var(--green); }
.asfm .notice-error, .asfm .error { border-left-color: var(--red); }
.asfm .notice-warning { border-left-color: var(--amber); }
.asfm .notice-info { border-left-color: var(--accent-solid); }
.asfm .notice-dismiss { display: none; }

/* Tabs */
.asfm .nav-tab-wrapper {
	display: flex; align-items: stretch; border-bottom: 1.5px solid var(--ink);
	overflow-x: auto; overflow-y: hidden; scrollbar-width: none;
	padding: 0; margin: 0 0 24px;
}
.asfm .nav-tab-wrapper::-webkit-scrollbar { display: none; }
.asfm .nav-tab {
	flex: none; display: inline-flex; align-items: center;
	min-height: 44px; padding: 10px 16px 10px 0; margin: 0 20px -1.5px 0;
	background: none; border: none; border-bottom: 3px solid transparent;
	font-family: var(--serif); font-weight: 900; font-size: 15px;
	letter-spacing: -.01em; color: var(--tx-mute); white-space: nowrap;
}
.asfm .nav-tab:hover { color: var(--tx); text-decoration: none; background: none; }
.asfm .nav-tab-active { color: var(--tx); border-bottom-color: var(--accent-solid); background: none; }

/*
 * The responsive table. Below the fold-width a row stops being a row and
 * becomes a small block, each value labelled by the column it came from.
 * A four-column table at 390px either scrolls sideways or lies.
 */
@media (max-width: 782px) {
	.asfm .asfm-table thead { display: none; }
	.asfm .asfm-table, .asfm .asfm-table tbody { display: block; width: 100%; }
	.asfm .asfm-table tr {
		display: block; padding: 14px 0; border-bottom: 1px solid var(--bd);
	}
	.asfm .asfm-table tr:hover { background: none; }
	.asfm .asfm-table td {
		display: flex; gap: 10px; align-items: baseline;
		border: 0; padding: 3px 0; width: auto !important;
	}
	.asfm .asfm-table td::before {
		content: attr(data-l); color: var(--tx-mute); font-size: 11px;
		font-weight: 700; letter-spacing: .06em; text-transform: uppercase;
		min-width: 96px; flex: 0 0 96px; line-height: 1.6;
	}
	.asfm .asfm-table td[data-l=""], .asfm .asfm-table td:not([data-l]) {
		display: block; padding-top: 0;
	}
	.asfm .asfm-table td[data-l=""]::before,
	.asfm .asfm-table td:not([data-l])::before { display: none; }
	.asfm .asfm-table td:first-child { display: block; padding-bottom: 6px; }
	.asfm .asfm-table td:first-child::before { display: none; }
	.asfm .asfm-table td:empty { display: none; }
	.asfm .asfm-table form { display: inline-block; }

	.asfm .form-table, .asfm .form-table tbody, .asfm .form-table tr,
	.asfm .form-table th, .asfm .form-table td { display: block; width: 100%; }
	.asfm .form-table th { padding: 14px 0 4px; }
	.asfm .form-table td { padding: 0 0 14px; }
	.asfm .regular-text { max-width: 100%; }
}

/* The Help button, in the same corner on every screen in the shop. */
.asfm .asfm-helpbutton {
	position: fixed; right: 18px; bottom: 18px; z-index: 400;
	display: inline-flex; align-items: center; gap: 6px;
	min-height: 44px; padding: 11px 18px; border-radius: 999px;
	background: var(--ink); color: #fff;
	font-size: 14px; font-weight: 600; text-decoration: none;
	box-shadow: var(--shadow-float);
}
.asfm .asfm-helpbutton:hover { background: var(--ink-l10); color: #fff; text-decoration: none; }
@media (max-width: 782px) {
	/* Above the bottom bar, not under it. */
	.asfm .asfm-helpbutton { bottom: calc(var(--mobilenav-h) + 14px); right: 14px; }
}

/* The way out of the shop, at the foot of the drawer. Quieter than the
   places inside it, because it leaves. */
.asfm .asfm-navout { opacity: .72; }
.asfm .asfm-navout:hover { opacity: 1; }

/* ─────────────────── a choice between two ways ───────────────────── */
/* Used where the difference between the options matters enough to be
   read rather than picked blind out of a dropdown. */
.asfm .asfm-choice {
	display: flex; gap: 10px; align-items: flex-start;
	border: 1px solid var(--bd); border-radius: 10px;
	padding: 12px 14px; margin-bottom: 8px; cursor: pointer;
	background: var(--card);
}
.asfm .asfm-choice:hover { border-color: var(--bd-strong); }
.asfm .asfm-choice:has(input:checked) {
	border-color: var(--accent-solid);
	background: var(--accent-wash);
}
.asfm .asfm-choice input { margin: 3px 0 0; flex: 0 0 auto; min-height: 0; }
.asfm .asfm-choice .asfm-help { margin: 2px 0 0; display: block; }

/* ─────────────────────── a video from somewhere else ─────────────── */
/* An embed has no natural height, so it is held in a 16:9 box. Any
   player that comes along later lands in the same shape. */
.asfm-embed {
	position: relative; width: 100%; aspect-ratio: 16 / 9;
	border-radius: 10px; overflow: hidden; background: var(--ink);
	margin: 0 0 20px;
}
.asfm-embed iframe { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; }
