/* Ionized HQ (/a/) — the portal shell. Layout plus the few pieces the shared component layer does
   not draw (sidebar, phone top bar, gate, embed bar). Values are the design tokens only —
   var(--ion-*) from theme/static/css/ionized-tokens.css (docs/DESIGN_SYSTEM.md §4.6): no hex, no
   font name, no size or tracking literal. The components themselves (.ion-panel, .ion-btn,
   .ion-status, .ion-table, .ion-flash, .ion-note, .eyebrow, the APP heading scale, the inputs)
   come from the theme_3 layer in styles.css, which <body class="theme-page-style3 portal">
   switches to APP density. Everything is scoped to the portal's own classes, so nothing leaks
   into the site. The shape follows the Wagtail admin (a left sidebar that collapses to icons, a
   drawer on phones). */

.portal {
	--side: 248px;
	--side-slim: 68px;
	--top: 56px;
	/* The site chrome's offsets (navigation/static/js/menu.js sets them on public pages): the
	   framed /o/ pages stick their bars at var(--menu-push). In the portal there is no fixed
	   site header — 0 on desktop, the phone top bar below 1024px. */
	--menu-push: 0px;
	--small-menu-push: 0px;
	--site-header-offset: 0px;
	--site-header-h: 0px;
	--site-ribbon-h: 0px;
	/* the ground (flat bg + the one fixed glow) is .theme-page-style3.portal in styles.css */
	color: var(--ion-ink);
	min-height: 100vh;
	margin: 0;
	font-family: var(--ion-body);
	font-size: var(--ion-fs-body);
	line-height: var(--ion-lh-body);
}
.portal *, .portal *::before, .portal *::after { box-sizing: border-box; }
.portal [x-cloak] { display: none !important; }

.portal-icon { width: 20px; height: 20px; flex: none; }

.portal-skip {
	position: absolute; left: -999px; top: var(--ion-sp-2); z-index: var(--ion-z-skip);
	padding: var(--ion-sp-2) var(--ion-sp-4);
	font-family: var(--ion-head); font-size: var(--ion-fs-cap); font-weight: 600;
	letter-spacing: var(--ion-tr-ui); text-transform: uppercase;
	color: var(--ion-bg); background: var(--ion-accent);
}
.portal-skip:focus { left: var(--ion-sp-2); }

/* Keyboard focus: an inset ring, like every clickable in the system (§2.8). */
.portal-iconbtn:focus-visible, .portal-item:focus-visible, .portal-quick a:focus-visible,
.portal-me-link:focus-visible, .portal-brand-link:focus-visible {
	outline: none; box-shadow: var(--ion-ring-focus);
}

/* ── sidebar (§3.9) ─────────────────────────────────────────────────────── */
.portal-side {
	position: fixed; inset: 0 auto 0 0; width: var(--side); z-index: var(--ion-z-chrome);
	display: flex; flex-direction: column;
	background: var(--ion-panel);
	border-right: 1px solid var(--ion-line);
	transition: width var(--ion-dur-base) var(--ion-ease), transform var(--ion-dur-base) var(--ion-ease);
}
.portal-brand {
	display: flex; align-items: center; gap: var(--ion-sp-2);
	height: var(--top); padding: 0 var(--ion-sp-3) 0 var(--ion-sp-4);
	border-bottom: 1px solid var(--ion-line);
}
.portal-brand-link, .portal-brand-mini {
	display: flex; align-items: center; gap: 10px; min-width: 0; flex: 1;
	text-decoration: none; white-space: nowrap; color: var(--ion-ink);
	font-family: var(--ion-head); font-size: var(--ion-fs-dense); font-weight: 700;
	letter-spacing: var(--ion-tr-label); text-transform: uppercase;
}
.portal-brand-link img, .portal-brand-mini img { width: 28px; height: 28px; flex: none; }
.portal-brand-link b, .portal-brand-mini b { color: var(--ion-accent); font-weight: 700; }

.portal-iconbtn {
	display: inline-flex; align-items: center; justify-content: center;
	width: 36px; height: 36px; flex: none; padding: 0;
	color: var(--ion-ink-soft); background: transparent; border: 1px solid transparent; border-radius: 0;
	cursor: pointer;
	transition: color var(--ion-dur-fast) ease, border-color var(--ion-dur-fast) ease;
}
.portal-iconbtn:hover { color: var(--ion-accent); border-color: var(--ion-line); }
.portal-collapse .portal-icon { transition: transform var(--ion-dur-base) var(--ion-ease); }
.portal-close { display: none; }

.portal-nav { flex: 1; overflow-y: auto; padding: var(--ion-sp-3) 0 var(--ion-sp-4); scrollbar-width: thin; }
.portal-group + .portal-group { margin-top: var(--ion-sp-4); }
.portal-group-label {
	margin: 0; padding: 0 18px 6px;
	font-family: var(--ion-head); font-size: var(--ion-fs-micro); font-weight: 600;
	letter-spacing: var(--ion-tr-label); line-height: 1.2; text-transform: uppercase;
	color: var(--ion-ink-faint);
}
/* A row: Chakra 500 13px .08em ink-soft · hover ink on panel-2 · the current page accent on the
   accent tint with the 3px left edge. */
.portal-item {
	display: flex; align-items: center; gap: var(--ion-sp-3);
	min-height: 44px; padding: 6px 18px;
	text-decoration: none; color: var(--ion-ink-soft);
	font-family: var(--ion-head); font-size: var(--ion-fs-small); font-weight: 500;
	letter-spacing: var(--ion-tr-ui); line-height: 1.2; text-transform: uppercase;
	transition: background-color var(--ion-dur-fast) ease, color var(--ion-dur-fast) ease;
}
.portal-item:hover { color: var(--ion-ink); background: var(--ion-panel-2); }
.portal-item[aria-current="page"] {
	color: var(--ion-accent);
	background: var(--ion-accent-tint);
	box-shadow: var(--ion-edge-left);
}
/* the current row keeps its edge while it has keyboard focus */
.portal-item[aria-current="page"]:focus-visible { box-shadow: var(--ion-edge-left), var(--ion-ring-focus); }
.portal-item .portal-text { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.portal-item .ion-status { flex: none; }
/* "opens in a new tab": a bare 16px mark, not a readout */
.portal-ext { display: inline-flex; flex: none; color: var(--ion-ink-faint); }
.portal-ext .portal-icon { width: 16px; height: 16px; }

.portal-me {
	display: flex; align-items: center; gap: 10px;
	padding: var(--ion-sp-3) var(--ion-sp-3) var(--ion-sp-3) var(--ion-sp-4);
	border-top: 1px solid var(--ion-line);
}
.portal-me-text { display: flex; flex-direction: column; min-width: 0; flex: 1; }
.portal-me-name { font-weight: 600; color: var(--ion-ink); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.portal-me-link { font-size: var(--ion-fs-small); color: var(--ion-ink-soft); text-decoration: none; }
.portal-me-link:hover { color: var(--ion-accent); }
.portal-logout { margin: 0; }

.portal-avatar {
	width: 32px; height: 32px; flex: none; border-radius: 50%; object-fit: cover;
	aspect-ratio: 1 / 1; border: 1px solid var(--ion-line-strong); background: var(--ion-panel-2);
}
.portal-avatar-lg { width: 56px; height: 56px; }
.portal-avatar-empty { display: inline-flex; align-items: center; justify-content: center; color: var(--ion-ink-faint); }

/* collapsed (desktop): icons only; labels stay for screen readers */
.portal-shell.is-collapsed .portal-side { width: var(--side-slim); }
.portal-shell.is-collapsed .portal-main { margin-left: var(--side-slim); }
.portal-shell.is-collapsed .portal-side .portal-label {
	position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap;
}
.portal-shell.is-collapsed .portal-brand { flex-direction: column; justify-content: center; height: auto; padding: 10px 0; }
.portal-shell.is-collapsed .portal-brand-link { flex: none; }
.portal-shell.is-collapsed .portal-item { justify-content: center; padding: 6px 0; }
.portal-shell.is-collapsed .portal-side .portal-group-label { height: 1px; padding: 0; margin: 6px var(--ion-sp-4); background: var(--ion-line); }
.portal-shell.is-collapsed .portal-collapse .portal-icon { transform: rotate(180deg); }
.portal-shell.is-collapsed .portal-me { flex-direction: column; padding: var(--ion-sp-3) 0; }

/* ── main column: APP page padding (§2.5) ────────────────────────────────── */
.portal-main {
	margin-left: var(--side); min-height: 100vh;
	padding: var(--ion-sp-6) clamp(var(--ion-sp-4), 3vw, 40px) var(--ion-sp-8);
	transition: margin-left var(--ion-dur-base) var(--ion-ease);
	outline: none;
}
/* the page head (.ion-page-head: eyebrow → h1 → .lead; the APP scale is styles.css's) */
.portal-head { margin-bottom: var(--ion-sp-5); }
.portal-title { margin: 0; }
/* a framed SITE page (/o/…, portal/site_frame.html): its own theme_3 grid lays the page out edge
   to edge (the .portal-shell prefix outranks the phone rule that pads a collapsed shell's main). */
.portal-shell .portal-main.portal-main-site { padding: 0 0 var(--ion-sp-8); }
/* Its first section's top padding (py-content / pt-content = 8rem) was room for the public
   site's FIXED header; in the pane nothing sits above it, so the page starts where a portal page
   does. After the /o/ feedback band (.o-flash) the content follows it closely. */
.portal-main-site > section:first-of-type:is(.py-content, .pt-content) { padding-top: 2rem; }
.portal-main-site > .o-flash + section:is(.py-content, .pt-content) { padding-top: 1.25rem; }

/* ── dashboard / account / members cards ─────────────────────────────────── */
.portal-cards {
	display: grid; gap: var(--ion-sp-4);
	grid-template-columns: repeat(auto-fill, minmax(min(100%, 304px), 1fr));
	align-items: start;
}
/* the card is an .ion-panel (16px padding in APP); its title an .ion-card-title */
.portal-card { display: flex; flex-direction: column; gap: var(--ion-sp-3); }
.portal-card > .ion-card-title { margin: 0; }
.portal-card-wide { margin-bottom: var(--ion-sp-4); }
.portal-card-big {
	margin: 0; color: var(--ion-ink);
	font-family: var(--ion-head); font-size: var(--ion-fs-xl); font-weight: 700;
	letter-spacing: var(--ion-tr-head); line-height: var(--ion-lh-snug); text-transform: uppercase;
}
.portal-vs { font-size: var(--ion-fs-dense); font-weight: 500; letter-spacing: var(--ion-tr-head); color: var(--ion-ink-faint); }
.portal-card-meta { margin: 0; font-size: var(--ion-fs-dense); line-height: var(--ion-lh-dense); color: var(--ion-ink-soft); }
.portal-card-links { margin: 0; font-size: var(--ion-fs-dense); color: var(--ion-ink-faint); }
.portal-card-links a { color: var(--ion-accent); text-decoration: none; }
.portal-card-links a:hover { text-decoration: underline; }

.portal-quick { display: flex; flex-direction: column; margin: 0; padding: 0; list-style: none; }
.portal-quick a {
	display: flex; align-items: center; gap: var(--ion-sp-3); min-height: 40px; padding: var(--ion-sp-1) 0;
	text-decoration: none; color: var(--ion-ink);
	border-bottom: 1px solid var(--ion-line);
	transition: color var(--ion-dur-fast) ease;
}
.portal-quick li:last-child a { border-bottom: 0; }
.portal-quick a:hover { color: var(--ion-accent); }
.portal-quick a span:first-of-type { flex: 1; }

.portal-idrow { display: flex; align-items: center; gap: var(--ion-sp-3); }
.portal-chips { display: flex; flex-wrap: wrap; gap: var(--ion-sp-2); margin: 0; padding: 0; list-style: none; }
.portal-maplist { display: flex; flex-direction: column; gap: var(--ion-sp-2); margin: 0; padding: 0; list-style: none; }
.portal-maplist li { display: flex; flex-wrap: wrap; align-items: center; gap: var(--ion-sp-2); }
.portal-maplist code { color: var(--ion-ink-faint); }

/* the members table is an .ion-table (.stack under 520px); a deactivated member reads faint */
.portal-table-wrap { overflow-x: auto; }
.portal-table tr.is-off td { color: var(--ion-ink-faint); }

.portal-flash { display: flex; flex-direction: column; gap: var(--ion-sp-2); margin: 0 0 20px; padding: 0; list-style: none; }

/* ── the gate (login / refused): no sidebar ─────────────────────────────── */
.portal-gate-wrap { min-height: 100vh; display: grid; place-items: center; padding: var(--ion-sp-5) var(--ion-sp-4); }
.portal .portal-gate-card { width: min(100%, 448px); display: flex; flex-direction: column; gap: var(--ion-sp-4); padding: var(--ion-sp-6); }
.portal-gate-card > * { margin: 0; }
.portal-gate-emblem { width: 56px; height: 56px; }
.portal-gate-text { color: var(--ion-ink-soft); }
.portal-gate-small { font-size: var(--ion-fs-small); color: var(--ion-ink-faint); }
.portal-gate-small a { color: var(--ion-ink-soft); }
.portal-gate-small a:hover { color: var(--ion-accent); }

/* ── a stream-kit page in the right pane (portal/embed.html) ─────────────── */
.portal-main.portal-main-embed { padding: 0; display: flex; flex-direction: column; height: 100vh; height: 100dvh; }
.portal-embed-bar {
	display: flex; align-items: center; gap: var(--ion-sp-3); flex-wrap: wrap;
	min-height: 44px; padding: 6px clamp(var(--ion-sp-4), 2vw, var(--ion-sp-5));
	background: var(--ion-panel); border-bottom: 1px solid var(--ion-line);
}
/* the title is a breadcrumb (section · page), a micro label — never a tab (§3.10) */
.portal-embed-title {
	margin: 0;
	font-family: var(--ion-head); font-size: var(--ion-fs-micro); font-weight: 600;
	letter-spacing: var(--ion-tr-label); line-height: 1.2; text-transform: uppercase;
	color: var(--ion-ink-soft);
}
.portal-embed-title b { font-weight: 600; color: var(--ion-ink); }
.portal-embed-note { font-size: var(--ion-fs-small); color: var(--ion-ink-faint); }
.portal-embed-actions { margin-left: auto; display: flex; gap: var(--ion-sp-2); }
.portal-embed-actions .portal-icon { width: 16px; height: 16px; }
.portal-frame { flex: 1; width: 100%; min-height: 0; display: block; border: 0; background: var(--ion-bg); }

/* ── a Riot tool in the right pane (portal/tool_frame.html): its section as the eyebrow ── */
.portal-tool-head { margin: 0 0 var(--ion-sp-2); }

/* ── phones / small tablets: the sidebar is a drawer ────────────────────── */
.portal-topbar { display: none; }
.portal-scrim { display: none; }
@media (max-width: 1023px) {
	.portal { --menu-push: var(--top); --small-menu-push: var(--top); --site-header-offset: var(--top); }
	.portal-topbar {
		display: flex; align-items: center; gap: var(--ion-sp-3);
		position: sticky; top: 0; z-index: var(--ion-z-sticky); height: var(--top); padding: 0 var(--ion-sp-3);
		background: var(--ion-panel); border-bottom: 1px solid var(--ion-line);
	}
	.portal-topbar .portal-avatar { margin-left: auto; }
	.portal-side { transform: translateX(-100%); width: min(85vw, var(--side)); }
	.portal-shell.is-open .portal-side { transform: none; }
	.portal-shell.is-collapsed .portal-side { width: min(85vw, var(--side)); }
	.portal-shell.is-collapsed .portal-side .portal-label { position: static; width: auto; height: auto; clip-path: none; }
	.portal-shell.is-collapsed .portal-item { justify-content: flex-start; padding: 6px 18px; }
	.portal-shell.is-collapsed .portal-side .portal-group-label { height: auto; padding: 0 18px 6px; margin: 0; background: none; }
	.portal-shell.is-collapsed .portal-brand { flex-direction: row; height: var(--top); padding: 0 var(--ion-sp-3) 0 var(--ion-sp-4); }
	.portal-shell.is-collapsed .portal-me { flex-direction: row; padding: var(--ion-sp-3) var(--ion-sp-3) var(--ion-sp-3) var(--ion-sp-4); }
	.portal-collapse { display: none; }
	.portal-close { display: inline-flex; }
	.portal-main, .portal-shell.is-collapsed .portal-main { margin-left: 0; padding-top: 20px; }
	/* a framed site page under the sticky top bar: flush, its first section as a portal page */
	.portal-shell .portal-main.portal-main-site { padding-top: 0; }
	.portal-main-site > section:first-of-type:is(.py-content, .pt-content) { padding-top: 1.25rem; }
	.portal-main.portal-main-embed { height: calc(100vh - var(--top)); height: calc(100dvh - var(--top)); }
	.portal-scrim {
		display: block; position: fixed; inset: 0; z-index: 35; background: rgb(var(--ion-bg-rgb) / .7);
	}
}

/* ── print (the /o/ scout + self sheets, any portal page): the page alone ── */
@media print {
	.portal-side, .portal-topbar, .portal-scrim, .portal-skip { display: none !important; }
	.portal-shell .portal-main, .portal-shell.is-collapsed .portal-main { margin-left: 0; padding: 0; min-height: 0; }
	.portal-main-site > section:first-of-type:is(.py-content, .pt-content) { padding-top: 0; }
}

@media (prefers-reduced-motion: reduce) {
	.portal-side, .portal-main, .portal-item, .portal-collapse .portal-icon, .portal-quick a, .portal-iconbtn { transition: none; }
}
