*, *::before, *::after { box-sizing: border-box; }
body { margin: 0; font-family: var(--font-body, system-ui, -apple-system, sans-serif); line-height: 1.6; color: var(--color-text, #1a1a2e); background: var(--color-bg, #fff); min-height: 100vh; display: flex; flex-direction: column; position: relative; }
main { flex: 1; }
a { color: var(--color-accent, #6366f1); }
.aup-skip-link {
position: absolute;
inset-inline-start: 1rem;
inset-block-start: -3.5rem;
z-index: 1000;
padding: 0.5rem 1rem;
border-radius: 4px;
background: var(--color-text, #1a1a2e);
color: var(--color-bg, #fff);
font-weight: 600;
text-decoration: none;
transition: inset-block-start 0.15s;
}
.aup-skip-link:focus {
inset-block-start: 1rem;
outline: 2px solid var(--color-accent, #6366f1);
outline-offset: 2px;
}
:root {
--page-max: var(--container-max, 1280px);
}
body > main {
width: 100%;
max-width: var(--aup-content-max, none);
margin-left: auto;
margin-right: auto;
box-sizing: border-box;
}
body > .aup-app-footer,
body > header.aup-app-header > .aup-app-header-bar,
body > header.aup-app-header > .aup-app-header-strip {
width: 100%;
max-width: var(--page-max);
margin-left: auto;
margin-right: auto;
padding-left: var(--page-gutter);
padding-right: var(--page-gutter);
box-sizing: border-box;
}
.container { max-width: var(--page-max); margin: 0 auto; padding: 0 var(--page-gutter); width: 100%; }
.page-header { padding: 3rem 0 2rem; }
.page-header h1 { margin: 0 0 0.5rem; font-size: 2rem; font-weight: 700; }
.page-header-desc { margin: 0; color: var(--color-text-muted, #64748b); font-size: 1.1rem; }
.section-header { padding: 2rem 0 1rem; }
.section-label { font-size: 0.85rem; text-transform: uppercase; letter-spacing: 0; color: var(--color-accent, #6366f1); margin-bottom: 0.25rem; }
.section-title { margin: 0 0 0.5rem; font-size: 1.5rem; font-weight: 600; }
.section-desc { margin: 0; color: var(--color-text-muted, #64748b); }
.aup-input-field,
.aup-editor {
display: grid;
gap: 0.45rem;
width: 100%;
}
.aup-input-label,
.aup-editor-label {
color: color-mix(in srgb, var(--color-text, #111827) 82%, var(--color-dim, #64748b));
font-size: 0.86rem;
font-weight: 720;
}
.aup-input-control,
.aup-editor-control {
width: 100%;
min-height: 2.65rem;
padding: 0.62rem 0.75rem;
border: 1px solid color-mix(in srgb, var(--color-border, #e2e8f0) 82%, transparent);
border-radius: var(--radius-lg, 8px);
color: var(--color-text, #111827);
background: color-mix(in srgb, var(--color-surface, #f8fafc) 92%, var(--color-bg, #fff));
font: inherit;
}
.aup-input-control:focus,
.aup-editor-control:focus {
outline: 2px solid color-mix(in srgb, var(--color-accent, #6366f1) 34%, transparent);
outline-offset: 1px;
border-color: color-mix(in srgb, var(--color-accent, #6366f1) 62%, var(--color-border, #e2e8f0));
}
.aup-input-control[role="switch"] {
width: 2.6rem;
min-height: 1.35rem;
accent-color: var(--color-accent, #6366f1);
}
.aup-input-control[type="range"] {
padding-inline: 0;
accent-color: var(--color-accent, #6366f1);
}
progress.aup-input-control {
padding: 0;
overflow: hidden;
accent-color: var(--color-accent, #6366f1);
}
.aup-editor-control {
min-height: 12rem;
font-family: var(--font-mono, ui-monospace, SFMono-Regular, Menlo, Consolas, monospace);
font-size: 0.92rem;
line-height: 1.55;
resize: vertical;
}
.aup-action[data-exec][data-exec-state="running"] {
cursor: wait;
opacity: 0.72;
}
.aup-action[data-exec][data-exec-state="error"] {
border-color: color-mix(in srgb, var(--color-error, #dc2626) 68%, var(--color-border, #e2e8f0));
}
.aup-exec-result {
margin-top: 0.55rem;
padding: 0.62rem 0.75rem;
border: 1px solid color-mix(in srgb, var(--color-border, #e2e8f0) 82%, transparent);
border-radius: var(--radius-lg, 8px);
background: color-mix(in srgb, var(--color-surface, #f8fafc) 94%, var(--color-bg, #fff));
color: color-mix(in srgb, var(--color-text, #111827) 84%, var(--color-dim, #64748b));
font-size: 0.86rem;
line-height: 1.45;
}
.aup-exec-result:empty {
display: none;
}
.aup-exec-result[data-state="success"] {
border-color: color-mix(in srgb, var(--color-success, #16a34a) 52%, var(--color-border, #e2e8f0));
color: var(--color-text, #111827);
}
.aup-exec-result[data-state="error"] {
border-color: color-mix(in srgb, var(--color-error, #dc2626) 58%, var(--color-border, #e2e8f0));
color: var(--color-error, #dc2626);
}
main .aup-view[data-variant="settings-sidebar"] {
position: sticky;
top: 88px;
max-height: calc(100vh - 112px);
overflow: auto;
padding: 1rem;
border: 1px solid color-mix(in srgb, var(--color-border, #e2e8f0) 78%, transparent);
border-radius: var(--radius-lg, 8px);
background:
linear-gradient(180deg, color-mix(in srgb, var(--color-accent, #6366f1) 9%, transparent), transparent 42%),
color-mix(in srgb, var(--color-surface, #f8fafc) 94%, var(--color-bg, #fff));
box-shadow: 0 20px 56px color-mix(in srgb, #000 10%, transparent);
}
main .aup-view[data-variant="settings-sidebar"] > .aup-text:first-child {
margin: 0 0 0.65rem;
padding: 0 0 0.8rem;
border-bottom: 1px solid color-mix(in srgb, var(--color-border, #e2e8f0) 70%, transparent);
color: var(--color-text, #111827);
font-size: 0.86rem;
font-weight: 800;
letter-spacing: 0;
text-transform: none;
}
main .aup-view[data-variant="settings-sidebar"] .aup-action {
min-height: 2.35rem;
margin: 0.12rem 0;
padding: 0.45rem 0.65rem;
border: 1px solid transparent;
border-radius: var(--radius-lg, 8px);
color: color-mix(in srgb, var(--color-text, #111827) 76%, var(--color-dim, #64748b));
font-weight: 700;
text-decoration: none;
}
main .aup-view[data-variant="settings-sidebar"] .aup-action:hover {
color: var(--color-text, #111827);
background: color-mix(in srgb, var(--color-accent, #6366f1) 8%, transparent);
}
main .aup-view[data-variant="settings-sidebar"] .aup-action[data-variant="primary"] {
width: 100%;
margin: 0.12rem 0;
border-color: color-mix(in srgb, var(--color-accent, #6366f1) 36%, transparent);
color: var(--color-text, #111827);
background:
linear-gradient(90deg, color-mix(in srgb, var(--color-accent, #6366f1) 16%, transparent), transparent),
color-mix(in srgb, var(--color-surface, #f8fafc) 86%, var(--color-accent, #6366f1));
box-shadow: none;
}
main .aup-view[data-variant="settings-content"] {
width: min(100%, 860px);
padding: 0.5rem 0 4rem;
}
main .aup-view[data-variant="settings-content"] > .aup-text[data-variant="badge"]:first-child {
width: fit-content;
margin: 0 0 1rem;
padding: 0.32rem 0.58rem;
border: 1px solid color-mix(in srgb, var(--color-accent, #6366f1) 34%, var(--color-border, #e2e8f0));
border-radius: 999px;
color: var(--color-accent, #6366f1);
background: color-mix(in srgb, var(--color-accent, #6366f1) 8%, transparent);
font-size: 0.78rem;
font-weight: 800;
letter-spacing: 0;
}
main .aup-view[data-variant="settings-content"] > .aup-text[data-level="1"] {
max-width: 780px;
margin: 0 0 1rem;
color: var(--color-text, #111827);
font-family: var(--font-heading, var(--font-body, system-ui, sans-serif));
font-size: clamp(2.4rem, 6vw, 4.8rem);
font-weight: 820;
line-height: 0.98;
letter-spacing: 0;
}
main .aup-view[data-variant="settings-content"] > .aup-text:not([data-level]):not([data-mode]) {
max-width: 760px;
margin: 0 0 1.05rem;
color: color-mix(in srgb, var(--color-text, #111827) 82%, var(--color-dim, #64748b));
font-size: 1.02rem;
line-height: 1.82;
}
main .aup-view[data-variant="settings-content"] > .aup-text[data-level="2"] {
margin: 2.5rem 0 0.75rem;
padding-top: 1.25rem;
border-top: 1px solid color-mix(in srgb, var(--color-border, #e2e8f0) 68%, transparent);
color: var(--color-text, #111827);
font-family: var(--font-heading, var(--font-body, system-ui, sans-serif));
font-size: clamp(1.45rem, 3vw, 2rem);
font-weight: 760;
line-height: 1.16;
letter-spacing: 0;
}
main .aup-view[data-variant="settings-content"] > .aup-view[data-layout="row"] {
gap: 0.75rem;
margin-top: 1.4rem;
}
main .aup-view[data-variant="settings-content"] > .aup-view[data-layout="row"] .aup-action {
min-height: 2.55rem;
padding: 0.55rem 0.9rem;
border: 1px solid color-mix(in srgb, var(--color-border, #e2e8f0) 72%, transparent);
border-radius: 999px;
color: var(--color-text, #111827);
background: color-mix(in srgb, var(--color-surface, #f8fafc) 86%, transparent);
font-weight: 800;
text-decoration: none;
box-shadow: none;
}
main .aup-view[data-variant="settings-content"] > .aup-view[data-layout="row"] .aup-action[data-variant="primary"] {
border-color: color-mix(in srgb, var(--color-accent, #6366f1) 52%, transparent);
color: var(--color-on-accent, #fff);
background: linear-gradient(
135deg,
var(--color-accent, #6366f1),
var(--color-accent-secondary, var(--color-accent, #6366f1))
);
}
main .aup-view[data-variant="settings-content"] > .aup-view[data-layout="row"] .aup-action:hover {
transform: translateY(-1px);
}
@media (max-width: 860px) {
main .aup-view[data-variant="settings-sidebar"] {
position: static;
width: 100% !important;
max-height: none;
}
main .aup-view[data-variant="settings-content"] {
width: 100%;
}
}
.aup-deck-frame .aup-overlay-shell.open,
.aup-overlay-shell.open {
display: block;
position: relative;
min-height: 160px;
width: 100%;
}
.aup-overlay-shell.open > .aup-overlay-backdrop {
position: absolute;
border-radius: var(--radius-lg, 12px);
}
.aup-overlay-shell.open > .aup-overlay-dialog,
.aup-overlay-shell.open > .aup-overlay-drawer {
position: absolute;
max-width: min(92%, 420px);
max-height: 70%;
}
.aup-overlay-shell[data-mode="toast"].open {
min-height: auto;
}
.aup-overlay-toast {
display: inline-flex;
gap: 0.5rem;
padding: 0.75rem 1rem;
border-radius: var(--radius-md, 8px);
background: var(--color-surface, #f8fafc);
border: 1px solid var(--color-border, #e2e8f0);
box-shadow: 0 8px 24px rgba(0,0,0,0.12);
}
.aup-explorer-shell,
.aup-surface-shell,
.aup-wm-shell,
.aup-chat-shell,
.aup-cmt-shell,
.aup-entity-overview-shell,
.aup-terminal-shell {
background: var(--card-bg, var(--color-surface, #fff));
border: var(--card-border, 1px solid var(--color-border, #e2e8f0));
border-radius: var(--radius-lg, 12px);
overflow: hidden;
}
.aup-explorer-header,
.aup-surface-chrome,
.aup-wm-titlebar,
.aup-chat-header,
.aup-cmt-header,
.aup-entity-overview-header,
.aup-terminal-titlebar {
display: flex;
align-items: center;
justify-content: space-between;
gap: 0.5rem;
padding: 0.55rem 0.85rem;
border-bottom: 1px solid var(--color-border, #e2e8f0);
font-weight: 600;
font-size: 0.9rem;
}
.aup-surface-badge,
.aup-wm-badge,
.aup-chat-badge,
.aup-cmt-badge {
font-size: 0.7rem;
font-weight: 700;
letter-spacing: 0.04em;
text-transform: uppercase;
color: var(--color-dim, #64748b);
}
.aup-explorer-list { list-style: none; margin: 0; padding: 0.35rem 0; }
.aup-explorer-item {
display: flex;
align-items: center;
gap: 0.5rem;
padding: 0.35rem 0.85rem;
font-size: 0.9rem;
}
.aup-explorer-path { margin-left: auto; color: var(--color-dim, #64748b); font-size: 0.75rem; font-family: ui-monospace, monospace; }
.aup-explorer-root { font-size: 0.75rem; color: var(--color-dim, #64748b); }
.aup-surface-content,
.aup-wm-body { padding: 0.85rem; }
.aup-chat-shell { min-height: 220px; max-height: 360px; }
.aup-cb-history { flex: 1; overflow: auto; padding: 0.75rem; display: flex; flex-direction: column; gap: 0.55rem; }
.aup-cb-msg { border-radius: 8px; padding: 0.5rem 0.7rem; background: color-mix(in srgb, var(--color-surface, #f8fafc) 90%, transparent); }
.aup-cb-msg-user { align-self: flex-end; background: color-mix(in srgb, var(--color-accent, #6366f1) 14%, transparent); }
.aup-cb-role { display: block; font-size: 0.7rem; font-weight: 700; text-transform: uppercase; color: var(--color-dim, #64748b); margin-bottom: 0.2rem; }
.aup-cb-bar { display: flex; gap: 0.4rem; padding: 0.55rem; border-top: 1px solid var(--color-border, #e2e8f0); }
.aup-cb-input { flex: 1; min-width: 0; padding: 0.4rem 0.55rem; border-radius: 6px; border: 1px solid var(--color-border, #e2e8f0); }
.aup-cb-send { padding: 0.4rem 0.75rem; border-radius: 6px; border: 1px solid var(--color-border, #e2e8f0); }
.aup-cb-bar--disabled { opacity: 0.65; }
.aup-chip-shell {
display: inline-flex;
align-items: center;
gap: 0.35rem;
padding: 0.2rem 0.65rem;
border-radius: 999px;
background: color-mix(in srgb, var(--color-accent, #6366f1) 10%, transparent);
color: var(--color-text, #111);
font-size: 0.85rem;
font-weight: 600;
margin-inline-end: 0.35rem;
}
.aup-chip-shell[data-color="success"] { background: color-mix(in srgb, #34a853 14%, transparent); color: #1e7e34; }
.aup-chip-shell[data-color="warning"] { background: color-mix(in srgb, #f9ab00 16%, transparent); color: #a66a00; }
.aup-chip-shell[data-color="error"] { background: color-mix(in srgb, #ea4335 14%, transparent); color: #c5221f; }
.aup-chip-shell[data-color="info"] { background: color-mix(in srgb, #1a73e8 12%, transparent); color: #1a73e8; }
.aup-chip-count {
min-width: 1.1rem;
padding: 0 0.3rem;
border-radius: 999px;
background: color-mix(in srgb, currentColor 12%, transparent);
font-size: 0.75rem;
text-align: center;
}
.aup-breadcrumb-shell .aup-breadcrumb-list {
display: flex;
flex-wrap: wrap;
gap: 0.25rem 0.35rem;
list-style: none;
margin: 0;
padding: 0;
font-size: 0.9rem;
}
.aup-breadcrumb-sep { margin: 0 0.15rem; color: var(--color-dim, #64748b); }
.aup-breadcrumb-current { font-weight: 600; }
.aup-kv-shell,
.aup-entity-card .aup-kv {
display: grid;
gap: 0.35rem;
padding: 0.65rem 0.85rem;
}
.aup-kv-row {
display: grid;
grid-template-columns: minmax(6rem, 34%) 1fr;
gap: 0.5rem;
padding: 0.25rem 0;
border-bottom: 1px solid color-mix(in srgb, var(--color-border, #e2e8f0) 70%, transparent);
font-size: 0.9rem;
}
.aup-kv-label { color: var(--color-dim, #64748b); font-weight: 600; }
.aup-kv-title,
.aup-entity-card-title {
margin: 0;
padding: 0.55rem 0.85rem 0;
font-size: 0.95rem;
font-weight: 700;
}
.aup-entity-cards { display: grid; gap: 0.65rem; padding: 0.65rem; }
.aup-entity-card {
border: 1px solid var(--color-border, #e2e8f0);
border-radius: var(--radius-md, 8px);
overflow: hidden;
}
.aup-pagination-shell {
display: inline-flex;
align-items: center;
gap: 0.65rem;
padding: 0.4rem 0.55rem;
border: 1px solid var(--color-border, #e2e8f0);
border-radius: 999px;
font-size: 0.85rem;
}
.aup-pagination-btn {
border: 0;
background: transparent;
color: var(--color-dim, #64748b);
cursor: not-allowed;
}
.aup-tooltip-shell {
position: relative;
display: inline-flex;
flex-direction: column;
align-items: flex-start;
gap: 0.35rem;
}
.aup-tooltip-content {
display: inline-block;
padding: 0.35rem 0.55rem;
border-radius: 6px;
background: var(--color-text, #111);
color: var(--color-bg, #fff);
font-size: 0.78rem;
max-width: 16rem;
}
.aup-terminal-shell { background: #0c0c0c; color: #e2e8f0; }
.aup-terminal-titlebar { border-bottom-color: #222; color: #94a3b8; }
.aup-terminal-body {
margin: 0;
padding: 0.75rem 0.9rem;
font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
font-size: 0.82rem;
line-height: 1.45;
white-space: pre-wrap;
min-height: 120px;
}
.aup-terminal-line { margin: 0; }
.aup-canvas-toolbar--static {
display: flex;
justify-content: space-between;
gap: 0.5rem;
padding: 0.4rem 0.65rem;
border-bottom: 1px solid var(--color-border, #e2e8f0);
font-size: 0.8rem;
color: var(--color-dim, #64748b);
}
.aup-canvas-area { padding: 0.5rem; }
.aup-cmt-list { padding: 0.65rem 0.85rem; display: grid; gap: 0.65rem; }
.aup-cmt-item {
border: 1px solid var(--color-border, #e2e8f0);
border-radius: 8px;
padding: 0.55rem 0.7rem;
}
.aup-cmt-meta {
display: flex;
justify-content: space-between;
gap: 0.5rem;
font-size: 0.8rem;
margin-bottom: 0.25rem;
}
.aup-cmt-body { margin: 0; font-size: 0.9rem; }
.aup-cmt-empty { padding: 0.85rem; color: var(--color-dim, #64748b); font-size: 0.9rem; }
.aup-calendar-agenda { display: grid; gap: 0.4rem; }
.aup-calendar-agenda-row { display: flex; gap: 0.75rem; font-size: 0.85rem; }
.aup-calendar-agenda-date { color: var(--color-dim, #64748b); min-width: 6rem; font-variant-numeric: tabular-nums; }
.aup-deck-widget-shell {
border: 1px solid var(--color-border, #e2e8f0);
border-radius: var(--radius-md, 8px);
overflow: hidden;
background: var(--color-surface, #fff);
}
.aup-deck-widget-chrome {
display: flex;
align-items: center;
justify-content: space-between;
gap: 0.5rem;
padding: 0.55rem 0.85rem;
border-bottom: 1px solid var(--color-border, #e2e8f0);
font-weight: 600;
font-size: 0.9rem;
}
.aup-deck-widget-badge {
font-size: 0.7rem;
font-weight: 700;
letter-spacing: 0.04em;
text-transform: uppercase;
color: var(--color-dim, #64748b);
}
.aup-deck-widget-body { padding: 0.85rem; }
.aup-deck-widget-note { margin: 0.5rem 0 0; font-size: 0.85rem; color: var(--color-dim, #64748b); }
.aup-afs-stat-value { font-size: 2rem; font-weight: 700; font-variant-numeric: tabular-nums; }
.aup-afs-stat-label { color: var(--color-dim, #64748b); font-size: 0.9rem; }
.aup-dropzone-area {
display: grid;
gap: 0.35rem;
place-items: center;
min-height: 8rem;
padding: 1.25rem;
border: 2px dashed var(--color-border, #e2e8f0);
border-radius: 8px;
text-align: center;
}
.aup-finance-table, .aup-natal-table { width: 100%; border-collapse: collapse; font-size: 0.9rem; }
.aup-finance-table th, .aup-finance-table td,
.aup-natal-table th, .aup-natal-table td {
text-align: left;
padding: 0.35rem 0.5rem;
border-bottom: 1px solid var(--color-border, #e2e8f0);
}
.aup-progress-track {
height: 0.85rem;
border-radius: 999px;
background: color-mix(in srgb, var(--color-border, #e2e8f0) 80%, transparent);
overflow: hidden;
}
.aup-progress-fill {
height: 100%;
background: var(--color-accent, #6366f1);
}
.aup-searchable-dropdown-current {
padding: 0.45rem 0.65rem;
border: 1px solid var(--color-border, #e2e8f0);
border-radius: 6px;
margin-bottom: 0.5rem;
}
.aup-searchable-dropdown-list { list-style: none; margin: 0; padding: 0; }
.aup-searchable-dropdown-item { padding: 0.3rem 0.5rem; }
.aup-searchable-dropdown-item.selected { font-weight: 700; }
.aup-webgl-placeholder {
display: grid;
place-items: center;
min-height: 10rem;
background: color-mix(in srgb, var(--color-accent, #6366f1) 8%, transparent);
border-radius: 8px;
font-weight: 700;
}
.aup-post-editor-body { width: 100%; min-height: 8rem; font-family: inherit; }
.aup-type-block-body { white-space: pre-wrap; font-size: 0.9rem; }
.aup-xeyes-shell { display: inline-flex; flex-wrap: wrap; align-items: center; justify-content: center; gap: 8px; padding: 16px 20px 8px; }
:root,
[data-tone][data-palette] {
  --ds-bg: var(--color-bg);
  --ds-surface: var(--color-surface);
  --ds-text: var(--color-text);
  --ds-dim: var(--color-dim);
  --ds-accent: var(--color-accent);
  --ds-accent-bg: var(--color-accent-bg);
  --ds-border: var(--color-border);
  --ds-error: var(--color-error);
  --ds-success: var(--color-success);
  --ds-radius: var(--radius-md);
  --ds-radius-sm: var(--radius-sm);
  --ds-radius-lg: var(--radius-lg);
  --ds-spacing: var(--space-element);
  --ds-spacing-block: var(--space-block);
  --ds-spacing-section: var(--space-section);
  --ds-font-body: var(--font-body);
  --ds-font-heading: var(--font-heading);
  --font-body: "Inter", "Noto Sans SC", "IBM Plex Sans JP", "Noto Sans JP", "PingFang SC", "Hiragino Kaku Gothic ProN", "Microsoft YaHei", system-ui, sans-serif;
  --color-dim: #52635d;
  --content-max: 44rem;
  --color-accent: #007b6a;
  --color-surface: #f4f7f5;
  --font-heading: "Sora", "Noto Sans SC", "IBM Plex Sans JP", "Noto Sans JP", "PingFang SC", "Hiragino Kaku Gothic ProN", "Microsoft YaHei", system-ui, sans-serif;
  --color-bg: #fcfdfc;
  --color-border: #d7e0dc;
  --container-max: 1120px;
  --font-mono: "JetBrains Mono", monospace;
  --color-text: #111a17;
  --card-bg: rgba(255, 255, 255, 0.9);
  --card-border: 1px solid rgba(29, 95, 84, 0.14);
  --color-accent-secondary: #1f7a6e;
  --color-hero-ink: #163b34;
  --color-hero-accent: #007b6a;
  --color-on-accent: #ffffff;
  --color-trace: #008f7a;
  --color-trace-soft: #d9f1eb;
  --font-display: "Sora", "Noto Sans SC", "IBM Plex Sans JP", "Noto Sans JP", "PingFang SC", "Hiragino Kaku Gothic ProN", "Microsoft YaHei", system-ui, sans-serif;
  --font-utility: "JetBrains Mono", "Noto Sans SC", "IBM Plex Sans JP", "Noto Sans JP", "PingFang SC", "Hiragino Kaku Gothic ProN", "Microsoft YaHei", ui-monospace, monospace;
  --grid-min-width: 250px;
  --heading-gradient: linear-gradient(135deg, #17211e, #008f7a 58%, #3152a3);
  --radius-lg: 6px;
  --shadow-card: 0 12px 34px rgba(25, 54, 48, 0.08);
  --shadow-hover: 0 18px 44px rgba(25, 54, 48, 0.11);
  --space-block: 20px;
  --space-section: 6rem;
  --type-display: clamp(4rem, 7.6vw, 8.2rem);
}
@media (prefers-color-scheme: dark) {
  :root:not([data-mode="light"]),
  [data-tone][data-palette]:not([data-mode="light"]) {
    --color-dim: #98a8a3;
    --color-accent: #2ec8ae;
    --color-surface: #101d1a;
    --color-bg: #061211;
    --color-border: #20302b;
    --color-text: #e8f2ee;
    --card-bg: rgba(14, 27, 25, 0.94);
    --card-border: 1px solid rgba(79, 217, 192, 0.16);
    --color-accent-secondary: #4fd9c0;
    --color-hero-ink: #d8e7e2;
    --color-hero-accent: #55d8c1;
    --color-on-accent: #06120f;
    --color-trace: #2ec8ae;
    --color-trace-soft: #163f38;
    --heading-gradient: linear-gradient(135deg, #ffffff, #33d8bf 58%, #7aa7ff);
    --shadow-card: 0 12px 34px rgba(0, 0, 0, 0.24);
    --shadow-hover: 0 18px 44px rgba(0, 0, 0, 0.32);
  }
}
[data-tone][data-palette][data-mode="dark"] {
  --color-dim: #98a8a3;
  --color-accent: #2ec8ae;
  --color-surface: #101d1a;
  --color-bg: #061211;
  --color-border: #20302b;
  --color-text: #e8f2ee;
  --card-bg: rgba(14, 27, 25, 0.94);
  --card-border: 1px solid rgba(79, 217, 192, 0.16);
  --color-accent-secondary: #4fd9c0;
  --color-hero-ink: #d8e7e2;
  --color-hero-accent: #55d8c1;
  --color-on-accent: #06120f;
  --color-trace: #2ec8ae;
  --color-trace-soft: #163f38;
  --heading-gradient: linear-gradient(135deg, #ffffff, #33d8bf 58%, #7aa7ff);
  --shadow-card: 0 12px 34px rgba(0, 0, 0, 0.24);
  --shadow-hover: 0 18px 44px rgba(0, 0, 0, 0.32);

}
.portal-header {
  position: sticky;
  top: 0;
  z-index: 1000;
  background: color-mix(in srgb, var(--color-bg, #fff) 82%, transparent);
  border-bottom: 1px solid transparent;
  padding: 0;
  backdrop-filter: blur(20px) saturate(1.1);
  transition:
    background 0.3s ease,
    border-color 0.3s ease;
}

.portal-header.scrolled {
  background: color-mix(in srgb, var(--color-bg, #fff) 92%, transparent);
  border-bottom-color: color-mix(in srgb, var(--color-border, #e5e7eb) 50%, transparent);
}

.portal-header .container {
  /* The header rides the shared content column (document-css --page-max /
     --page-gutter). Because it centers in the viewport on the SAME column as
     each section's content, brand/actions align with the body at every width
     with no reserve hack and no separate --header-content-max token. The
     .portal-header element keeps its full-bleed sticky background; only this
     container is bounded. */
  width: 100%;
  max-width: var(--page-max);
  margin: 0 auto;
  padding: 0 var(--page-gutter);
  display: flex;
  align-items: center;
  justify-content: space-between;
  min-height: 76px;
  gap: 1.5rem;
  transition:
    min-height 0.2s ease,
    padding-block 0.2s ease;
}

/* Scroll-compact sticky state (arc#2390): toggled by script.js past a small
   scroll offset so the header doesn't permanently occupy its full height
   while reading long content. Desktop already fits one row, so this is a
   subtle height trim there; on mobile — where the compact layout below still
   spends real vertical space on a single row — it matters more. */
.portal-header.scrolled .container {
  min-height: 60px;
}

/* Header grammar: left group holds logo + main nav; right group holds
   language picker, mode toggle, and a reserved user-menu slot. */
.portal-header .header-left {
  min-width: 0;
  display: flex;
  align-items: center;
  gap: clamp(1.5rem, 3vw, 2.6rem);
}

.portal-header .logo {
  min-width: max-content;
  display: inline-flex;
  align-items: center;
  gap: 0.55rem;
  font-family: var(--font-display, "Sora", system-ui, sans-serif);
  font-weight: 460;
  font-size: 1.05rem;
  letter-spacing: -0.01em;
  color: var(--color-text, #0f172a);
  text-decoration: none;
}

.portal-header .logo .logo-mark {
  display: inline-block;
  width: 0.7rem;
  height: 0.7rem;
  border-radius: 2px;
  background: linear-gradient(
    135deg,
    var(--color-accent, #2563eb),
    var(--color-accent-secondary, var(--color-accent, #2563eb))
  );
}

/* When the site provides an inline SVG logo, hide the textual site name —
   the SVG is the brand mark — and size the SVG to header height. */
.portal-header .logo .logo-svg {
  display: inline-flex;
  align-items: center;
}

.portal-header .logo img.logo-svg,
.portal-header .logo .logo-svg svg {
  height: 1.65rem;
  width: auto;
  display: block;
  /* The wordmark uses currentColor so it follows light/dark mode; the
     branded gradient mark inside the SVG keeps its own colors. */
  color: var(--color-text, #0f172a);
}

.portal-header.has-logo-svg .logo {
  gap: 0;
}

.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

.portal-header .main-nav {
  display: flex;
  align-items: center;
  gap: 1.4rem;
  padding: 0;
  border: 0;
  border-radius: 0;
  background: transparent;
}

.portal-header .main-nav a {
  font-family: var(--font-mono, "JetBrains Mono", ui-monospace, monospace);
  display: inline-flex;
  align-items: center;
  padding: 0.4rem 0;
  font-size: 0.72rem;
  font-weight: 500;
  color: var(--color-dim, #6b7280);
  text-decoration: none;
  text-transform: uppercase;
  letter-spacing: 0.16em;
  transition: color 0.2s ease;
  position: relative;
}

.portal-header .main-nav a::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 1px;
  background: var(--color-accent, #2563eb);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 0.2s ease;
}

.portal-header .main-nav a:hover {
  color: var(--color-text, #0f172a);
}

.portal-header .main-nav a:hover::after {
  transform: scaleX(1);
}

/* Header controls: optional CTA + locale picker + mode toggle + user slot. */
.portal-header .header-controls {
  display: flex;
  align-items: center;
  gap: 0.42rem;
}

/* Primary CTA (nav item with variant:"cta") — a filled accent pill sized to
   the 32px control row so it reads as the header's main action rather than a
   stray label. Marketing sites opt in per nav item; default nav links are
   unaffected. */
.portal-header .nav-cta {
  display: inline-flex;
  align-items: center;
  height: 32px;
  padding: 0 0.95rem;
  margin-right: 0.25rem;
  border-radius: 999px;
  background: var(--color-accent, #2563eb);
  color: var(--accent-fg, #fff);
  font-family: var(--font-body, "Inter", system-ui, sans-serif);
  font-size: 0.78rem;
  font-weight: 600;
  letter-spacing: 0.01em;
  text-decoration: none;
  white-space: nowrap;
  transition:
    background 0.2s ease,
    transform 0.2s ease;
}

.portal-header .nav-cta:hover {
  background: color-mix(in srgb, var(--color-accent, #2563eb) 88%, #000);
  transform: translateY(-1px);
}

.portal-header .user-slot:empty {
  display: none;
}

.portal-header .user-slot {
  display: flex;
  align-items: center;
  gap: 0.42rem;
  margin-left: 0;
}

/* Align the runtime-rendered header-actions strip (.web/template/header-actions
   → .aup-app-header-action buttons, e.g. the anonymous Login trigger) with the
   portal control pills above: same 32px round pill, transparent fill, dim
   stroke/glyph, and accent hover. Only presentation — markup stays owned by
   the shared SSR renderer. */
.portal-header .user-slot .aup-app-header-action {
  width: 32px;
  height: 32px;
  padding: 0;
  border-radius: 999px;
  background: transparent;
  border: 1px solid color-mix(in srgb, var(--color-border, #e5e7eb) 60%, transparent);
  color: var(--color-dim, #6b7280);
}

.portal-header .user-slot .aup-app-header-action:hover {
  color: var(--color-text, #0f172a);
  background: transparent;
  border-color: color-mix(in srgb, var(--color-accent, #2563eb) 40%, var(--color-border, #e5e7eb));
}

.portal-header .user-slot .aup-app-header-action svg {
  width: 16px;
  height: 16px;
}

/* Post-hydration authenticated state: keep the avatar trigger on the same
   32px control row. */
.portal-header .user-slot .aup-app-header-user-menu-trigger {
  height: 32px;
  box-sizing: border-box;
}

/* Mobile section-nav menu toggle (arc#2390) — hidden above the compact
   breakpoint (desktop keeps the inline nav; this button doesn't exist there
   visually), sized/shown by the compact-layout media query below. */
.portal-header-menu-toggle {
  display: none;
  align-items: center;
  justify-content: center;
  border: 1px solid color-mix(in srgb, var(--color-border, #e5e7eb) 60%, transparent);
  border-radius: 999px;
  background: transparent;
  color: var(--color-dim, #6b7280);
  cursor: pointer;
  padding: 0;
  transition:
    background 0.2s,
    color 0.2s,
    border-color 0.2s;
}

.portal-header-menu-toggle:hover {
  color: var(--color-text, #0f172a);
  border-color: color-mix(in srgb, var(--color-accent, #2563eb) 40%, var(--color-border, #e5e7eb));
}

.portal-header-menu-toggle .icon-menu-close {
  display: none;
}

.portal-header.nav-open .portal-header-menu-toggle .icon-menu-open {
  display: none;
}

.portal-header.nav-open .portal-header-menu-toggle .icon-menu-close {
  display: block;
}

/* Click-outside-to-close backdrop for the mobile nav drawer. Sits below the
   sticky header (same stacking context) and above page content. */
.portal-header-backdrop {
  position: fixed;
  inset: 0;
  z-index: 998;
  background: color-mix(in srgb, #000 32%, transparent);
  border: 0;
  padding: 0;
  -webkit-tap-highlight-color: transparent;
}

.portal-header-backdrop[hidden] {
  display: none;
}

.portal-header .locale-picker {
  position: relative;
}

.portal-header .locale-picker-btn,
.portal-header .mode-toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.35rem;
  height: 32px;
  padding: 0 0.65rem;
  border: 1px solid color-mix(in srgb, var(--color-border, #e5e7eb) 60%, transparent);
  border-radius: 999px;
  background: transparent;
  color: var(--color-dim, #6b7280);
  cursor: pointer;
  transition:
    background 0.2s,
    color 0.2s,
    border-color 0.2s;
  font-family: var(--font-mono, "JetBrains Mono", ui-monospace, monospace);
  font-size: 0.7rem;
  font-weight: 500;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}

/* Both are icon-only square pills (the locale picker is now a globe-only
   trigger aligned with the AUP app-header locale-switcher). */
.portal-header .locale-picker-btn,
.portal-header .mode-toggle {
  width: 32px;
  padding: 0;
}

.portal-header .locale-picker-btn:hover,
.portal-header .mode-toggle:hover {
  color: var(--color-text, #0f172a);
  border-color: color-mix(in srgb, var(--color-accent, #2563eb) 40%, var(--color-border, #e5e7eb));
}

.portal-header .locale-picker-btn .icon-globe {
  transition: transform 0.2s;
}

.portal-header .locale-dropdown {
  position: absolute;
  top: calc(100% + 6px);
  right: 0;
  min-width: 152px;
  background: color-mix(in srgb, var(--color-bg, #fff) 96%, transparent);
  border: 1px solid color-mix(in srgb, var(--color-border, #e5e7eb) 70%, transparent);
  border-radius: 12px;
  box-shadow: 0 22px 48px color-mix(in srgb, var(--color-text, #0f172a) 12%, transparent);
  padding: 6px;
  z-index: 100;
  backdrop-filter: blur(18px);
  display: flex;
  flex-direction: column;
}

.portal-header .locale-dropdown[hidden] {
  display: none;
}

.portal-header .locale-option {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  width: 100%;
  padding: 0.5rem 0.8rem;
  border: none;
  border-radius: 8px;
  background: transparent;
  color: var(--color-dim, #6b7280);
  font-family: var(--font-body, "Inter", system-ui, sans-serif);
  font-size: 0.86rem;
  font-weight: 460;
  text-align: left;
  cursor: pointer;
  transition:
    background 0.15s,
    color 0.15s;
}

.portal-header .locale-option:hover {
  background: color-mix(in srgb, var(--color-accent, #2563eb) 6%, transparent);
  color: var(--color-text, #0f172a);
}

.portal-header .locale-option.active {
  color: var(--color-accent, #2563eb);
  font-weight: 540;
}

.portal-header .locale-option.active::before {
  content: "•";
  color: var(--color-accent, #2563eb);
  font-weight: 700;
}

/* Show sun by default, moon when dark */
.portal-header .mode-toggle .icon-moon {
  display: none;
}
.portal-header .mode-toggle .icon-sun {
  display: block;
}
.portal-header .mode-toggle.is-dark .icon-moon {
  display: block;
}
.portal-header .mode-toggle.is-dark .icon-sun {
  display: none;
}

@media (max-width: 860px) {
  .portal-header .container {
    min-height: auto;
    /* Horizontal gutter stays var(--page-gutter) (shared column); only add
       vertical breathing room now that the row can wrap. */
    padding-block: 0.5rem;
    flex-wrap: wrap;
    gap: 0.75rem;
  }

  /* Only let the left group grow when it actually holds a nav (which needs the
     room / scrolls). A logo-only left group must stay its natural width, or it
     expands to fill the row and pushes the controls onto a second line — the
     stray line-break on minimal headers like aside. */
  .portal-header .container:has(.main-nav a) .header-left {
    flex: 1 1 auto;
    min-width: 0;
    gap: 1.25rem;
  }

  .portal-header .header-controls {
    flex-shrink: 0;
  }

  .portal-header .main-nav {
    max-width: 100%;
    overflow-x: auto;
    scrollbar-width: none;
    gap: 1rem;
  }

  .portal-header .main-nav::-webkit-scrollbar {
    display: none;
  }

  .portal-header .main-nav a {
    white-space: nowrap;
  }
}

/* Compact mobile layout (arc#2390) — replaces the old behavior of stacking
   logo / section-nav / controls into three permanent rows (the actual bug
   reported: a sticky header eating a third of a 390×844 viewport). Brand +
   every essential action (nav entry point, language, theme, account) now
   stay on ONE row; the section nav moves into an expandable panel that
   overlays the page instead of pushing it down. Breakpoint matches the
   shared primitives-css.ts mobile cutoff (640px) for consistency across the
   fleet's header surfaces. */
@media (max-width: 640px) {
  .portal-header .container {
    flex-wrap: nowrap;
    min-height: 56px;
    padding-block: 0.4rem;
    gap: 0.5rem;
    /* .main-nav becomes an absolutely-positioned drawer below; .portal-header
       (position: sticky) is its containing block, so this only needs to stay
       a normal (non-positioned) flex row — no layout shift when the drawer
       opens/closes. */
  }

  /* The scrolled state's height floor is bounded below by the 44px touch
     targets themselves (criterion: every control stays >=44x44 in every
     state, scrolled included — so icons/pills never shrink here). The
     available lever is vertical padding: trimming it still yields a real,
     visible compaction (~58px -> ~49px) without an accessibility trade-off. */
  .portal-header.scrolled .container {
    min-height: 48px;
    padding-block: 0.15rem;
  }

  /* Matches (and overrides) the 860px block's `:has(.main-nav a) .header-left`
     rule at equal specificity + later source order — the nav no longer shares
     this row at all (it's an absolutely-positioned drawer, see .main-nav
     below), so the left group is just [logo, menu-toggle] and must stay
     content-sized instead of growing to fill the row. */
  .portal-header .container:has(.main-nav a) .header-left,
  .portal-header .header-left {
    flex: 0 1 auto;
    min-width: 0;
    gap: 0.35rem;
  }

  /* The nav no longer shares the row (it moved into the drawer below), so the
     left group is just the logo — never let it grow/shrink oddly. */
  .portal-header .logo {
    min-width: 0;
    overflow: hidden;
  }

  .portal-header .header-controls {
    flex-shrink: 0;
    gap: 0.25rem;
  }

  .portal-header .nav-cta {
    padding: 0 0.65rem;
    margin-right: 0;
    height: 44px;
  }

  /* Section-nav drawer: taken out of the row entirely and overlaid full-width
     below the header. Hidden (zero height, non-interactive) until
     .portal-header.nav-open is set by script.js's menu-toggle handler. */
  .portal-header .main-nav {
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    flex-direction: column;
    align-items: stretch;
    gap: 0;
    max-width: none;
    max-height: 0;
    overflow: hidden;
    overflow-x: visible;
    visibility: hidden;
    opacity: 0;
    background: var(--color-bg, #fff);
    border-bottom: 1px solid color-mix(in srgb, var(--color-border, #e5e7eb) 60%, transparent);
    box-shadow: 0 16px 32px color-mix(in srgb, var(--color-text, #0f172a) 10%, transparent);
    padding: 0 var(--page-gutter);
    transition:
      max-height 0.25s ease,
      opacity 0.2s ease,
      visibility 0.25s;
  }

  .portal-header.nav-open .main-nav {
    /* Bounded rather than unlimited, so a site with a long section list
       scrolls internally instead of pushing content below the viewport. */
    max-height: min(70vh, 420px);
    overflow-y: auto;
    visibility: visible;
    opacity: 1;
  }

  .portal-header .main-nav a {
    white-space: normal;
    width: 100%;
    min-height: 44px;
    padding: 0.7rem 0;
    font-size: 0.92rem;
    font-weight: 500;
    text-transform: none;
    letter-spacing: normal;
    border-bottom: 1px solid color-mix(in srgb, var(--color-border, #e5e7eb) 40%, transparent);
  }

  .portal-header .main-nav a:last-child {
    border-bottom: 0;
  }

  .portal-header .main-nav a::after {
    display: none;
  }

  .portal-header-menu-toggle {
    display: inline-flex;
  }

  /* Touch targets: every icon/control button must be at least 44×44 CSS px
     on touch-sized viewports (WCAG 2.5.5 / Apple & Material HIG), even though
     the desktop control row uses a tighter 32px pill. */
  .portal-header-menu-toggle,
  .portal-header .locale-picker-btn,
  .portal-header .mode-toggle {
    width: 44px;
    height: 44px;
  }

  .portal-header .user-slot .aup-app-header-action,
  .portal-header .user-slot .aup-app-header-user-menu-trigger {
    width: 44px;
    height: 44px;
  }
}

.site-footer {
  background: color-mix(in srgb, var(--color-bg, #fff) 94%, var(--color-accent, #008f7a) 6%);
  border-top: 1px solid color-mix(in srgb, var(--color-border, #d7dfdc) 72%, transparent);
  margin-top: 0;
  padding: clamp(2.5rem, 5vw, 4.25rem) 0 1.5rem;
}

.site-footer .container {
  margin: 0 auto;
  max-width: var(--page-max);
  padding: 0 var(--page-gutter);
}

.site-footer .footer-top {
  align-items: start;
  display: grid;
  gap: clamp(1.25rem, 3vw, 3rem);
  /* Two children today: the brand block and the link nav. The connection slot
     is optional and currently absent, so declaring its track unconditionally
     left an empty 0px column whose `gap` still applied, pushing the links one
     whole gap (48px at 1920, 3vw below that) short of the right edge. The
     track count has to follow the children that actually render. */
  grid-template-columns: minmax(0, 1fr) auto;
  padding-bottom: clamp(1.5rem, 3vw, 2.2rem);
}

.site-footer .footer-top.has-connection {
  grid-template-columns: minmax(0, 1fr) auto auto;
}

.site-footer .footer-brand-block {
  display: grid;
  gap: 0.8rem;
  max-width: 34rem;
}

.site-footer .footer-brand {
  align-items: center;
  display: inline-flex;
  text-decoration: none;
  width: fit-content;
}

.site-footer .footer-logo-svg,
.site-footer .footer-logo-svg svg,
.site-footer img.footer-logo-svg {
  color: var(--color-hero-ink, #163b34);
  display: block;
  height: 1.9rem;
  width: auto;
}

.site-footer .footer-logo-name {
  color: var(--color-hero-ink, #163b34);
  font-family: var(--font-display, "Sora", sans-serif);
  font-size: 1.08rem;
  font-weight: 650;
}

.site-footer .footer-tagline {
  word-break: keep-all;
  overflow-wrap: anywhere;
  color: var(--color-dim, #5d706b);
  font-family: var(--font-body, "Inter", sans-serif);
  font-size: 0.9rem;
  line-height: 1.65;
  margin: 0;
}

.site-footer .footer-social {
  align-items: center;
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem;
  margin-top: 0.15rem;
}

.site-footer .footer-social-link {
  align-items: center;
  border: 1px solid transparent;
  border-radius: 999px;
  color: var(--color-dim, #5d706b);
  display: inline-flex;
  height: 2rem;
  justify-content: center;
  transition: background-color 140ms ease, border-color 140ms ease, color 140ms ease;
  width: 2rem;
}

.site-footer .footer-social-link:hover {
  background: color-mix(in srgb, var(--color-accent, #008f7a) 9%, transparent);
  border-color: color-mix(in srgb, var(--color-accent, #008f7a) 22%, transparent);
  color: var(--color-accent, #008f7a);
}

.site-footer .footer-social-link svg {
  display: block;
  height: 1rem;
  width: 1rem;
}

.site-footer .footer-grid,
.site-footer .footer-grid[data-count="1"],
.site-footer .footer-grid[data-count="2"],
.site-footer .footer-grid[data-count="3"] {
  align-self: center;
  display: block;
}

.site-footer .footer-col ul,
.site-footer .footer-legal {
  align-items: center;
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem 1rem;
  list-style: none;
  margin: 0;
  padding: 0;
}

.site-footer .footer-col li {
  margin: 0;
}

.site-footer .footer-col a,
.site-footer .footer-legal a,
.site-footer .footer-connection a {
  color: var(--color-dim, #5d706b);
  font-family: var(--font-body, "Inter", sans-serif);
  font-size: 0.88rem;
  line-height: 1.5;
  text-decoration: none;
  text-underline-offset: 0.2em;
}

.site-footer .footer-col a:hover,
.site-footer .footer-legal a:hover,
.site-footer .footer-connection a:hover {
  color: var(--color-accent, #008f7a);
  text-decoration: underline;
}

.site-footer .footer-connection {
  border-left: 1px solid color-mix(in srgb, var(--color-border, #d7dfdc) 74%, transparent);
  display: grid;
  gap: 0.35rem;
  max-width: 18rem;
  padding-left: clamp(1rem, 2vw, 1.75rem);
}

.site-footer .footer-connection h2 {
  color: var(--color-hero-ink, #163b34);
  font-family: var(--font-body, "Inter", sans-serif);
  font-size: 0.92rem;
  font-weight: 650;
  margin: 0;
}

.site-footer .footer-connection p {
  color: var(--color-dim, #5d706b);
  font-size: 0.84rem;
  line-height: 1.55;
  margin: 0;
}

.site-footer .footer-bottom {
  align-items: center;
  border-top: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem 1.5rem;
  justify-content: space-between;
  padding-top: 0;
}

.site-footer .footer-bottom p {
  color: var(--color-dim, #5d706b);
  font-family: var(--font-body, "Inter", sans-serif);
  font-size: 0.79rem;
  line-height: 1.5;
  margin: 0;
}

.site-footer .visually-hidden {
  border: 0;
  clip: rect(0, 0, 0, 0);
  height: 1px;
  margin: -1px;
  overflow: hidden;
  padding: 0;
  position: absolute;
  white-space: nowrap;
  width: 1px;
}

/* The global chrome stays quiet: enlarge only the formal mark, never the menu. */
.portal-header .container {
  min-height: clamp(4.45rem, 5.2vw, 5.05rem);
}

/* Inline SVG keeps width="199" height="56". Size the mark from height +
   viewBox aspect ratio; do not let the wrapper take the intrinsic 199px or
   the compact header overflow:hidden clips "ArcBlock" to "ArcBloc". */
.portal-header .logo .logo-svg {
  display: inline-flex;
  align-items: center;
  height: auto;
  max-width: 100%;
  width: auto;
}

.portal-header .logo .logo-svg svg,
.portal-header .logo .logo-svg img {
  aspect-ratio: 199 / 56;
  display: block;
  height: clamp(2rem, 2.55vw, 2.45rem);
  max-width: 100%;
  width: auto;
}

.portal-header .main-nav a,
.portal-header .header-controls,
.portal-header .header-controls button,
.portal-header .header-controls a {
  font-size: 0.84rem;
}

.site-footer a:focus-visible,
.portal-header a:focus-visible,
.portal-header button:focus-visible {
  outline: 2px solid var(--color-accent, #008f7a);
  outline-offset: 3px;
}

@media (max-width: 760px) {
  .site-footer {
    padding-top: 2.6rem;
  }

  .site-footer .footer-top {
    gap: 1.15rem;
    grid-template-columns: 1fr;
  }

  .site-footer .footer-grid {
    border-top: 0;
    padding-top: 1rem;
  }

  .site-footer .footer-connection {
    border-left: 0;
    border-top: 0;
    max-width: none;
    padding: 1rem 0 0;
  }

  .site-footer .footer-bottom {
    align-items: flex-start;
    flex-direction: column;
  }

  .portal-header .container {
    min-height: 4.25rem;
  }

  .portal-header .logo .logo-svg svg,
  .portal-header .logo .logo-svg img {
    height: 1.95rem;
    max-width: 100%;
  }
}

@media (prefers-reduced-motion: reduce) {
  .site-footer *,
  .portal-header * {
    scroll-behavior: auto !important;
    transition-duration: 0.01ms !important;
  }
}

/* Shared site Hero system; emitted once by the common site chrome. */
/* The content object supplies the signature; shared type and tokens tie them together. */
.object-hero{position:relative;isolation:isolate;overflow:clip;color:var(--color-text);background:var(--color-bg);border-bottom:1px solid var(--color-border)}
.object-hero *{box-sizing:border-box}.oh-inner{max-width:var(--page-max,1120px);margin:auto;padding:64px var(--page-gutter,24px) 60px;display:grid;grid-template-columns:minmax(0,1.35fr) minmax(0,1fr);gap:60px;align-items:center;min-height:430px}.oh-copy{position:relative;z-index:1;min-width:0}.oh-eyebrow{display:flex;align-items:center;gap:18px;font:12px/1.5 var(--font-utility);letter-spacing:.07em;color:var(--color-accent);margin-bottom:22px}.oh-status{letter-spacing:0;color:var(--color-dim);border-left:1px solid var(--color-border);padding-left:18px}.object-hero h1{margin:0;font:600 clamp(40px,4.7vw,66px)/1.08 var(--font-display);letter-spacing:-.055em;text-wrap:balance;overflow-wrap:anywhere}.object-hero:lang(zh) h1,.object-hero:lang(zh-TW) h1,.object-hero:lang(ja) h1{line-height:1.22;letter-spacing:-.025em;word-break:normal}.oh-description{max-width:37em;margin:24px 0 0;font:400 17px/1.8 var(--font-body);color:var(--color-dim);text-wrap:pretty}.oh-actions{display:flex;flex-wrap:wrap;gap:12px 24px;margin-top:30px}.oh-action{display:inline-flex;align-items:center;justify-content:space-between;gap:24px;padding:12px 18px;background:var(--color-accent);color:var(--color-on-accent);border:1px solid transparent;border-radius:5px;font:500 14px/1.5 var(--font-body);text-decoration:none}.oh-action:hover{filter:brightness(.93)}.oh-action--quiet{color:var(--color-text);background:transparent;border-color:var(--color-border)}.oh-action:focus-visible{outline:3px solid var(--color-accent);outline-offset:4px}.oh-visual{min-width:0;position:relative}.oh-small{font:12px/1.7 var(--font-utility);color:var(--color-dim)}
.oh--products{background:radial-gradient(ellipse at 82% 40%,color-mix(in srgb,var(--color-accent) 12%,transparent),transparent 60%),var(--color-bg)}.oh-products{position:relative;height:285px}.oh-products figure{margin:0;overflow:hidden;border:1px solid var(--color-border);background:var(--color-surface);box-shadow:0 20px 42px #002d211c}.oh-browser{width:90%;position:absolute;top:25px;left:0;transform:rotate(-5deg);border-radius:10px}.oh-browser img{display:block;width:100%;height:200px;object-fit:cover;object-position:top}.oh-products figcaption{display:flex;justify-content:space-between;padding:11px 14px;font:11px var(--font-utility)}.oh-products figcaption span{color:var(--color-dim)}.oh-phone{position:absolute;right:-8px;top:0;width:119px;transform:rotate(8deg);border-radius:21px;border:5px solid var(--color-text)!important}.oh-phone img{display:block;width:100%;height:235px;object-fit:cover;object-position:top}.oh-phone figcaption{padding:9px 6px;font-size:9px}
.oh-form-board{padding:28px 32px;background:linear-gradient(140deg,color-mix(in srgb,var(--color-accent) 9%,var(--color-bg)),var(--color-surface));border:1px solid var(--color-border);border-radius:14px}.oh-form-board ul{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));list-style:none;margin:24px 0 0;padding:0;gap:20px}.oh-form-board li{font:500 13px/1.5 var(--font-body);display:flex;align-items:center;gap:10px;overflow-wrap:anywhere}.oh-form-board li:only-child{grid-column:1/-1;font-size:27px}.oh-form-icon{color:var(--color-accent);font:32px/1.2 var(--font-display)}
.oh--event .oh-inner{grid-template-columns:minmax(0,1.2fr) minmax(0,1fr)}.oh-date-board{border-top:3px solid var(--color-accent);padding:24px 0}.oh-date-board strong{display:block;margin:24px 0;font:500 clamp(28px,3.3vw,45px)/1.25 var(--font-display);letter-spacing:-.045em;text-wrap:balance}.oh-date-board p{margin:12px 0 0;color:var(--color-dim);font-size:15px}.oh-event-lines{border-left:1px solid var(--color-border);padding:12px 0 12px 40px}.oh-event-lines>span{font:12px var(--font-utility);color:var(--color-dim)}.oh-event-lines strong{display:block;margin-top:28px;font:500 46px/1.05 var(--font-display);letter-spacing:-.06em;color:var(--color-accent)}.oh-event-lines strong span{display:block;color:var(--color-text)}.oh-event-lines i{display:block;margin-top:30px;height:12px;background:repeating-linear-gradient(90deg,var(--color-border) 0 1px,transparent 1px 18px)}
.oh--docs .oh-inner,.oh--glossary .oh-inner{min-height:375px;padding-block:50px}.oh-books{height:225px;display:flex;gap:10px;align-items:flex-end;justify-content:center;transform:rotate(-6deg)}.oh-books>div{height:205px;width:75px;border:1px solid var(--color-border);border-top:4px solid var(--color-accent);background:var(--color-surface);padding:16px;display:flex;align-items:center;justify-content:space-between;writing-mode:vertical-rl;border-radius:3px 5px 5px 3px;font:500 20px var(--font-display)}.oh-books>div:first-child{height:225px;width:125px;background:color-mix(in srgb,var(--color-accent) 10%,var(--color-bg));align-items:flex-start}.oh-books small{font:10px var(--font-utility);color:var(--color-dim)}.oh-type{display:flex;align-items:baseline;justify-content:center;gap:12px;font:500 130px/1 var(--font-display);letter-spacing:-.1em;color:var(--color-accent)}.oh-type span+span{font-size:90px;opacity:.45}.oh--text .oh-inner{display:block;min-height:0;max-width:var(--page-max,1120px)}.oh--term .oh-copy{max-width:850px}.oh--term h1{font-size:clamp(48px,6vw,80px)}.oh--term .oh-description{font-size:20px;line-height:1.85;max-width:42em;color:var(--color-text)}.oh-alias{font:14px/1.6 var(--font-utility);color:var(--color-accent);margin:18px 0 0}
@media(max-width:760px){.oh-inner,.oh--event .oh-inner{grid-template-columns:1fr;gap:28px;padding:34px var(--page-gutter,16px) 36px;min-height:0}.object-hero h1{font-size:clamp(34px,8vw,48px)}.oh-eyebrow{margin-bottom:16px}.oh-description{font-size:16px;margin-top:18px}.oh-actions{margin-top:24px}.oh--docs .oh-inner,.oh--glossary .oh-inner{min-height:0;padding-block:34px}.oh--docs .oh-visual,.oh--glossary .oh-visual,.oh--events .oh-visual{display:none}.oh-products{height:225px;max-width:370px;margin:0 auto}.oh-browser img{height:155px}.oh-phone{width:94px;right:8px}.oh-phone img{height:185px}.oh-products figcaption{font-size:10px}.oh-phone figcaption{font-size:8px}.oh-form-board{padding:22px}.oh-form-board ul{margin-top:14px;gap:12px}.oh-form-board li{font-size:12px}.oh-date-board{padding:18px 0 0}.oh-date-board strong{font-size:30px;margin:12px 0}.oh--term .oh-description{font-size:18px}.oh--term h1{font-size:52px}}
.oh-date-board--calendar strong{font-size:clamp(66px,7.5vw,104px);line-height:1;letter-spacing:-.065em;color:var(--color-accent);font-variant-numeric:tabular-nums}.oh-date-board--calendar>.oh-small{font-size:16px;color:var(--color-text)}
@media(max-width:760px){.oh-date-board--calendar strong{font-size:64px}}
.oh-products figcaption a{color:inherit;text-decoration:none}.oh-products figcaption a:hover{text-decoration:underline}.oh-products figcaption a:focus-visible{outline:2px solid var(--color-accent);outline-offset:3px}.oh-preview-note{position:absolute;top:100%;left:0;right:0;margin:16px 0 0;font:10px/1.5 var(--font-utility);color:var(--color-dim)}
@media(max-width:760px){.oh--products .oh-inner{padding-bottom:58px}.oh-preview-note{margin-top:6px}}

/* One brand atmosphere across three Hero families. The cube is the exact official vector,
   cropped as a quiet background imprint; type and content always sit above it. */
html :is(.object-hero,.realm-hero,.arc-product-hero,.landing-hero,.post-hero,.docs-heading){
  position:relative;isolation:isolate;
  background:radial-gradient(ellipse at 78% 32%,color-mix(in srgb,var(--color-accent) 10%,transparent),transparent 58%),linear-gradient(150deg,color-mix(in srgb,var(--color-accent) 3%,var(--color-bg)),var(--color-bg));
}
html :is(.object-hero,.realm-hero,.arc-product-hero,.landing-hero,.post-hero,.docs-heading)::after{
  content:"";position:absolute;inset:0;z-index:-1;pointer-events:none;
  background:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI0OC4wMDM4IiBoZWlnaHQ9IjU1LjQzIiB2aWV3Qm94PSIwIDAgNDguMDAzOCA1NS40MyI+CjxwYXRoIG9wYWNpdHk9IjAuNiIgZmlsbC1ydWxlPSJldmVub2RkIiBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik0yMy4yNTE5IDI2LjQxNTlWMjcuMjgyTDIyLjUwMTkgMjcuNzE1TDAuODkxOTY4IDQwLjE5MTVMMS42NDIwMyA0MS40OTA2TDI0LjAwMiAyOC41ODExTDQ2LjM2MTkgNDEuNDkwNkw0Ny4xMTIgNDAuMTkxNUwyNS41MDIxIDI3LjcxNUwyNC43NTIxIDI3LjI4MlYyNi40MTU5VjEuNDYyODlIMjMuMjUxOVYyNi40MTU5WiIgZmlsbD0idXJsKCNwYWludDBfbGluZWFyXzU3XzMpIj48L3BhdGg+CjxwYXRoIGZpbGwtcnVsZT0iZXZlbm9kZCIgY2xpcC1ydWxlPSJldmVub2RkIiBkPSJNMjQuMDAxOSAwTDQ4LjAwMzggMTMuODU3NVY0MS41NzI1TDI0LjAwMTkgNTUuNDNMMCA0MS41NzI1VjEzLjg1NzVMMjQuMDAxOSAwWk0yLjI1MDE4IDE0LjI5MDVMMTcuMTc2NCAyMi45MDgyTDI0LjAwMTkgMTEuMDg2TDMwLjgyNzQgMjIuOTA4Mkw0NS43NTM2IDE0LjI5MDVMMjQuMDAxOSAxLjczMjE5TDIuMjUwMTggMTQuMjkwNVpNNDYuNTAzNyAxNS41ODk3TDMxLjU3NzUgMjQuMjA3M0wzOC40MDMgMzYuMDI5NUwyNC43NTIgNDMuOTExVjUzLjI2NDhMNDYuNTAzNyA0MC43MDY0VjE1LjU4OTdaTTIzLjI1MTggNTMuMjY0OFY0My45MTFMOS42MDA3NiAzNi4wMjk1TDE2LjQyNjMgMjQuMjA3M0wxLjUwMDEyIDE1LjU4OTdWNDAuNzA2NEwyMy4yNTE4IDUzLjI2NDhaTTE3LjcyNTQgMjQuOTU3NEwxMS42NSAzNS40ODA0TDIzLjI1MTggNDIuMTc4OFYyOS4wMTQxVjI4LjE0OEwyMi41MDE4IDI3LjcxNUwxNy43MjU0IDI0Ljk1NzRaTTI0Ljc1MiA0Mi4xNzg4TDM2LjM1MzggMzUuNDgwNEwzMC4yNzg0IDI0Ljk1NzRMMjUuNTAyIDI3LjcxNUwyNC43NTIgMjguMTQ4VjI5LjAxNDFWNDIuMTc4OFpNMjkuNTI4MyAyMy42NTgyTDI0LjAwMTkgMTQuMDg2MkwxOC40NzU1IDIzLjY1ODJMMjQuMDAxOSAyNi44NDg5TDI5LjUyODMgMjMuNjU4MloiIGZpbGw9InVybCgjcGFpbnQxX2xpbmVhcl81N18zKSI+PC9wYXRoPgo8ZGVmcz4KPGxpbmVhckdyYWRpZW50IGlkPSJwYWludDBfbGluZWFyXzU3XzMiIHgxPSI4MC4zMzgxIiB5MT0iMjAuNjE1NCIgeDI9IjQwLjYxODMiIHkyPSI4MS44MzY4IiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSI+CjxzdG9wIHN0b3AtY29sb3I9IiM0RUYxQkEiPjwvc3RvcD4KPHN0b3Agb2Zmc2V0PSIwLjUwMTkwNCIgc3RvcC1jb2xvcj0iIzE2Q0VEMSI+PC9zdG9wPgo8c3RvcCBvZmZzZXQ9IjEiIHN0b3AtY29sb3I9IiMzNzczRjIiPjwvc3RvcD4KPC9saW5lYXJHcmFkaWVudD4KPGxpbmVhckdyYWRpZW50IGlkPSJwYWludDFfbGluZWFyXzU3XzMiIHgxPSIyNC4wMDE5IiB5MT0iLTI3LjcxNSIgeDI9Ii0zMC44NTk2IiB5Mj0iMTkuNzk2NCIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiPgo8c3RvcCBzdG9wLWNvbG9yPSIjNEVGMUJBIj48L3N0b3A+CjxzdG9wIG9mZnNldD0iMC41MDE5MDQiIHN0b3AtY29sb3I9IiMxNkNFRDEiPjwvc3RvcD4KPHN0b3Agb2Zmc2V0PSIxIiBzdG9wLWNvbG9yPSIjMzc3M0YyIj48L3N0b3A+CjwvbGluZWFyR3JhZGllbnQ+CjxjbGlwUGF0aCBpZD0iY2xpcDBfNTdfMyI+CjxyZWN0IHdpZHRoPSIxOTkiIGhlaWdodD0iNTYiIGZpbGw9IndoaXRlIj48L3JlY3Q+CjwvY2xpcFBhdGg+CjwvZGVmcz4KPC9zdmc+Cg==') no-repeat right -65px center / 480px auto;opacity:.055;
}
.realm-page .realm-orbit{background:none}.realm-page .realm-orbit::before{display:none}
/* Presentation family: generous space, consistent action treatment, native artwork retained. */
:is(.realm-hero,.arc-product-hero,.landing-hero,.oh--product){border-radius:0;border-bottom:1px solid var(--color-border)}
.oh--product .oh-inner{min-height:510px;padding-block:72px}
:is(.landing-hero-title,.oh--product h1){color:var(--color-text);font-family:var(--font-display);font-weight:600}
:is(.landing-hero-action,.realm-action,.oh-action){border-radius:5px}
/* Collection family: one measure, two framed images, unchanged content below. */
.oh--index .oh-inner{min-height:430px;padding-block:56px;grid-template-columns:minmax(0,1.35fr) minmax(0,1fr);gap:60px}
.oh--index h1{font-size:clamp(40px,4.7vw,66px)}
.oh-photo-stack{position:relative;height:285px;max-width:425px;margin:auto}
.oh-photo-stack figure{position:absolute;margin:0;width:83%;border:1px solid var(--color-border);border-radius:10px;background:var(--color-surface);box-shadow:0 18px 36px #002d211a;overflow:hidden}
.oh-photo-stack figure:first-child{left:0;top:8px;transform:rotate(-5deg)}
.oh-photo-stack figure:last-child{right:0;top:100px;width:67%;transform:rotate(7deg)}
.oh-photo-stack a{display:block;color:var(--color-text);text-decoration:none}
.oh-photo-stack img{display:block;width:100%;height:176px;object-fit:cover}
.oh-photo-stack figure:last-child img{height:133px}
.oh-photo-stack figcaption{display:flex;justify-content:space-between;gap:10px;padding:10px 12px;font:11px/1.5 var(--font-body)}
.oh-photo-stack a:hover figcaption{color:var(--color-accent)}
.oh-photo-stack a:focus-visible{outline:3px solid var(--color-accent);outline-offset:-4px}
#main>.content-cards-wrap--article-index{width:100%;max-width:none;padding-top:0}
.content-cards-wrap--article-index>.content-cards{width:min(100% - 36px,820px);margin:40px auto 0}
@media(max-width:760px){
  .oh--index .oh-inner{grid-template-columns:1fr;min-height:0;padding:34px var(--page-gutter,16px) 48px;gap:28px}
  .oh--index h1{font-size:clamp(34px,8vw,48px)}
  .oh--index .oh-visual{display:block;width:100%}
  .oh-photo-stack{height:225px;max-width:330px;width:100%}
  .oh-photo-stack img{height:140px}.oh-photo-stack figure:last-child{top:75px}.oh-photo-stack figure:last-child img{height:107px}
  .oh-photo-stack figcaption{font-size:10px;padding:8px 10px}
  .oh--product .oh-inner{min-height:0;padding-block:40px}
  html :is(.object-hero,.realm-hero,.arc-product-hero,.landing-hero,.post-hero,.docs-heading)::after{background-size:330px auto;background-position:right -130px top -35px;opacity:.04}
}
/* Match collection silhouettes even when a title wraps to two CJK lines. */
@media(min-width:761px){
 .oh--index .oh-inner{min-height:460px;padding-block:48px}
 .oh--index h1{font-size:clamp(40px,4.3vw,60px)}
 .landing-hero .landing-hero-inner{min-height:580px;padding-block:76px;grid-template-columns:minmax(0,1.35fr) minmax(0,1fr);gap:60px}
 .landing-hero .landing-hero-title{max-width:none;font-size:clamp(calc(46px * var(--landing-hero-scale,1)),calc(5.4vw * var(--landing-hero-scale,1)),calc(78px * var(--landing-hero-scale,1)));line-height:1.16;letter-spacing:-.045em}
 .landing-hero:lang(zh) .landing-hero-title,.landing-hero:lang(zh-TW) .landing-hero-title,.landing-hero:lang(ja) .landing-hero-title{line-height:1.22;letter-spacing:0}
 .landing-hero-subtitle{font-size:17px;line-height:1.85;margin-top:24px}
}

/* Product destinations follow ARC's centered introduction, with their own source metadata. */
.oh--product .oh-inner{display:block;text-align:center;max-width:var(--page-max,1120px);padding:68px var(--page-gutter,24px) 52px}
.oh--product .oh-copy{max-width:940px;margin:auto}
.oh--product .oh-eyebrow,.oh--product .oh-actions{justify-content:center}
.oh--product h1{font-size:clamp(52px,6.6vw,94px)}
.oh--product .oh-description{max-width:650px;margin:24px auto 0}
.oh--product .oh-visual{max-width:920px;margin:48px auto 0;text-align:left}
.oh--product .oh-form-board{background:transparent;border:0;border-top:1px solid var(--color-border);border-radius:0;padding:26px 0 0}
.oh--product .oh-form-board ul{display:flex;flex-wrap:wrap;gap:24px 36px;margin-top:22px}
.oh--product .oh-form-board li:only-child{font-size:20px}
.landing-hero .landing-hero-inner{display:block;text-align:center;min-height:520px;padding-block:72px}
.landing-hero .landing-hero-copy{max-width:940px;margin:auto}
.landing-hero .landing-hero-title{max-width:none}
.landing-hero .landing-hero-subtitle{max-width:680px;margin:24px auto 0}
.landing-hero .landing-hero-actions{justify-content:center}
.landing-hero .landing-hero-trace{max-width:920px;margin:48px auto 0;min-height:180px;border-left:0;border-top:1px solid var(--color-border)}
.landing-hero .landing-hero-trace::before,.landing-hero .landing-trace-origin,.landing-hero .landing-trace-line{display:none}
@media(max-width:760px){
 .oh--product .oh-inner,.landing-hero .landing-hero-inner{padding:42px var(--page-gutter,16px) 40px;min-height:0}
 .oh--product h1{font-size:clamp(42px,11vw,58px)}
 .oh--product .oh-visual{margin-top:34px}
 .oh--product .oh-form-board ul{gap:18px 22px}
 .landing-hero .landing-hero-title{font-size:clamp(calc(36px * var(--landing-hero-scale,1)),calc(10vw * var(--landing-hero-scale,1)),calc(48px * var(--landing-hero-scale,1)));line-height:1.22;letter-spacing:0}
 .landing-hero .landing-hero-trace{margin-top:30px}
}

.landing-hero img.landing-hero-geometry{height:auto;object-fit:contain;aspect-ratio:48.0038 / 55.43}
.landing-hero img.landing-hero-geometry{width:120px;right:24px;bottom:16px}
/* At the top, chrome and Hero meet without a border or frosted slab. The existing
   header controller restores a solid navigation surface after scrolling. */
html body:has(:is(.object-hero,.realm-hero,.arc-product-hero,.landing-hero,.post-hero,.docs-heading)) .portal-header:not(.scrolled){background:var(--color-bg);border-bottom-color:transparent;box-shadow:none;backdrop-filter:none}
html body .portal-header{transition:background-color .22s ease,box-shadow .22s ease,border-color .22s ease}
html body .portal-header.scrolled{background:color-mix(in srgb,var(--color-bg) 94%,transparent);border-bottom-color:var(--color-border);box-shadow:0 6px 24px #001b1208;backdrop-filter:blur(16px)}
html :is(.object-hero,.realm-hero,.arc-product-hero,.landing-hero,.post-hero,.docs-heading){
 background:linear-gradient(var(--color-bg),transparent 120px),radial-gradient(ellipse at 78% 32%,color-mix(in srgb,var(--color-accent) 10%,transparent),transparent 58%),linear-gradient(150deg,color-mix(in srgb,var(--color-accent) 3%,var(--color-bg)),var(--color-bg));
}
html :is(.object-hero,.realm-hero,.arc-product-hero,.landing-hero,.post-hero,.docs-heading)::after{
 transform:translate3d(0,var(--hero-drift,0px),0);mask-image:linear-gradient(transparent,#000 100px,#000 calc(100% - 30px),transparent);
}
@keyframes arc-hero-enter{from{opacity:.72;transform:translateY(10px)}to{opacity:1;transform:translateY(0)}}
@media(prefers-reduced-motion:no-preference){
 :is(.oh-copy,.landing-hero-copy,.arc-product-heading,.post-hero-content){animation:arc-hero-enter .55s cubic-bezier(.2,.7,.2,1) both}
 .oh-photo-stack{animation:arc-hero-enter .7s cubic-bezier(.2,.7,.2,1) both}
 .oh-photo-stack figure{transition:box-shadow .22s ease}
 .oh-photo-stack figure:hover{box-shadow:0 22px 44px #002d2129}
}
@media(prefers-reduced-motion:reduce){
 html :is(.object-hero,.realm-hero,.arc-product-hero,.landing-hero,.post-hero,.docs-heading)::after{transform:none}
 html body .portal-header{transition:none}
}
/* Authored source labels stay a compact fact strip; the complete brand mark
   already appears in the background, so do not duplicate it over those labels. */
.landing-hero .landing-hero-trace{display:flex;align-items:center;justify-content:space-between;gap:24px;min-height:76px;padding:22px 24px;text-align:left}
.landing-hero .landing-hero-trace::after,.landing-hero .landing-hero-trace .landing-hero-geometry{display:none}
.landing-hero .landing-trace-kicker,.landing-hero .landing-trace-text{position:static;max-width:none;margin:0}

/* A quiet forward-emerging deck. Fixed stage preserves the collection Hero measure. */
.oh-photo-stack.oh-deck{height:285px;max-width:425px;perspective:1000px}
.oh-deck figure,.oh-deck figure:first-child,.oh-deck figure:last-child{left:5%;right:auto;top:22px;width:90%;height:226px;transform:translate3d(0,0,0);border-radius:12px;transform-origin:center;opacity:0;z-index:0;pointer-events:none;transition:transform 1200ms cubic-bezier(.22,.65,.25,1),opacity 900ms ease,box-shadow 1200ms ease;will-change:auto}
.oh-deck figure[data-position="0"]{transform:translate3d(0,18px,0);opacity:1;z-index:3;pointer-events:auto;box-shadow:0 16px 32px #002d2120}
.oh-deck figure[data-position="1"]{transform:translate3d(10px,-3px,-55px) rotate(3deg);opacity:.8;z-index:2}
.oh-deck figure[data-position="2"]{transform:translate3d(-8px,-23px,-110px) rotate(-3deg);opacity:.5;z-index:1}
.oh-deck figure[data-position="3"]{transform:translate3d(0,-35px,-165px);opacity:0;z-index:0}
.oh-deck figure[data-position="leaving"]{transform:translate3d(0,35px,45px);opacity:0;z-index:4}
.oh-deck figure img,.oh-deck figure:last-child img{height:174px;object-fit:cover}
.oh--products .oh-deck figure img,.oh--docs .oh-deck figure img{object-fit:contain;background:var(--color-bg)}
.oh-deck figure figcaption{height:52px;align-items:center;font:12px/1.45 var(--font-body);padding:9px 14px}
.oh-deck figcaption>span:first-child{display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
@media(max-width:760px){
 .oh-photo-stack.oh-deck{height:245px;max-width:330px}
 .oh-deck figure,.oh-deck figure:first-child,.oh-deck figure:last-child{height:192px;top:15px}
 .oh-deck figure img,.oh-deck figure:last-child img{height:140px}
 .oh-deck figure figcaption{font-size:11px}
}
@media(prefers-reduced-motion:reduce){.oh-photo-stack.oh-deck figure{transition:none}}

/* Film-frame variant: one unbroken image surface, captions appear only on intent. */
.oh-deck figure,.oh-deck figure:first-child,.oh-deck figure:last-child{background:var(--color-bg);border-radius:9px;border:1px solid color-mix(in srgb,var(--color-border) 75%,transparent)}
.oh-deck figure a{position:relative;width:100%;height:100%;display:block;overflow:hidden}
.oh-deck figure img,.oh-deck figure:last-child img{width:100%;height:100%;object-fit:contain;background:var(--color-bg)}
.oh-deck figure::before{content:"";position:absolute;inset:5px 8px auto;height:3px;z-index:2;pointer-events:none;opacity:.28;background:radial-gradient(circle at 2px 1.5px,var(--color-dim) 1.3px,transparent 1.5px) left top/9px 3px repeat-x;mask-image:linear-gradient(90deg,#000 0 26px,transparent 26px calc(100% - 26px),#000 calc(100% - 26px))}
.oh-deck figure::after{content:"";position:absolute;inset:5px;border:1px solid color-mix(in srgb,var(--color-border) 35%,transparent);border-radius:5px;pointer-events:none}
.oh-deck figure figcaption{position:absolute;left:0;right:0;bottom:0;height:auto;min-height:64px;align-items:flex-end;padding:30px 16px 13px;background:linear-gradient(transparent,rgba(3,16,14,.86));color:#fff;opacity:0;transform:translateY(5px);transition:opacity .25s ease,transform .25s ease;pointer-events:none;font-size:12px;line-height:1.5}
.oh-deck figure a:hover figcaption,.oh-deck figure a:focus-visible figcaption{opacity:1;transform:none;color:#fff}
.oh-deck figure a:focus-visible{outline:3px solid var(--color-accent);outline-offset:-3px}
@media(hover:none){.oh-deck figure[data-position="0"] figcaption{opacity:1;transform:none}}
@media(prefers-reduced-motion:reduce){.oh-photo-stack.oh-deck figure figcaption{transition:none;transform:none}}

/* Shared motion, distinct material: vocabulary cards, document folders, product film. */
.oh--glossary .oh-deck figure{background:var(--color-surface);border-radius:7px;border-color:color-mix(in srgb,var(--color-accent) 22%,var(--color-border))}
.oh--glossary .oh-deck figure::before{display:none}
.oh--glossary .oh-deck figure::after{inset:13px;border:0;border-left:1px solid color-mix(in srgb,var(--color-accent) 22%,transparent);border-radius:0}
.oh-flash-face{height:100%;padding:24px 28px 22px;display:flex;flex-direction:column;justify-content:center;color:var(--color-text);background:linear-gradient(145deg,var(--color-bg),var(--color-surface))}
.oh-flash-label{font:10px/1.4 var(--font-utility);color:var(--color-accent);letter-spacing:.08em;margin-bottom:12px}
.oh-flash-face strong{font:500 clamp(23px,2.2vw,30px)/1.2 var(--font-display);overflow-wrap:anywhere;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
.oh-flash-face p{font:12px/1.7 var(--font-body);color:var(--color-dim);margin:14px 0 0;display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;overflow:hidden}
.oh-flash-arrow{position:absolute;right:18px;top:18px;color:var(--color-accent);opacity:0;transition:opacity .2s}
.oh--glossary .oh-deck a:hover .oh-flash-arrow,.oh--glossary .oh-deck a:focus-visible .oh-flash-arrow{opacity:1}
.oh--docs .oh-deck figure{border-radius:5px 12px 5px 5px;background:var(--color-surface)}
.oh--docs .oh-deck figure::before{inset:0 auto auto 16px;width:62px;height:7px;opacity:1;background:var(--color-accent);border-radius:0 0 3px 3px;mask-image:none}
.oh--docs .oh-deck figure::after{inset:9px;border-radius:2px;border-color:color-mix(in srgb,var(--color-border) 55%,transparent)}
.oh--docs .oh-deck figure img{padding:10px;background:var(--color-surface)}
.oh--products .oh-deck figure::after{inset:5px;border-radius:4px;border-color:color-mix(in srgb,var(--color-accent) 18%,transparent)}
.oh--events .oh-deck figure::before,.oh--articles .oh-deck figure::before{display:none}
.oh--events .oh-deck figure,.oh--articles .oh-deck figure{border-radius:7px}
@media(max-width:760px){.oh-flash-face{padding:19px 24px}.oh-flash-label{margin-bottom:8px}.oh-flash-face strong{font-size:24px}.oh-flash-face p{font-size:11px;line-height:1.6;margin-top:10px}}
@media(prefers-reduced-motion:reduce){.oh-flash-arrow{transition:none}}
/* Desktop has room for the content itself to be more legible; mobile stays compact. */
@media(min-width:1024px){
 .oh--index .oh-inner{grid-template-columns:minmax(0,1.1fr) minmax(0,1fr);gap:40px}
 .oh-photo-stack.oh-deck{height:325px;max-width:480px;width:100%}
 .oh-deck figure,.oh-deck figure:first-child,.oh-deck figure:last-child{left:3%;width:94%;height:270px;top:22px}
 .oh-flash-face{padding:30px 34px}
 .oh-flash-face strong{font-size:32px}
 .oh-flash-face p{font-size:14px;line-height:1.7}
}
.oh--index:lang(zh) h1,.oh--index:lang(zh-TW) h1,.oh--index:lang(ja) h1{word-break:keep-all;overflow-wrap:anywhere}

/* Study-card marginalia: deterministic variation, decorative strokes rather than invented notes. */
.oh-flash-face strong span{padding-inline:3px;box-decoration-break:clone;-webkit-box-decoration-break:clone;background:linear-gradient(177deg,transparent 58%,color-mix(in srgb,var(--color-accent) 16%,transparent) 60% 89%,transparent 92%)}
.oh-deck figure[data-doodle="1"] .oh-flash-face strong span{background:linear-gradient(3deg,transparent 10%,color-mix(in srgb,var(--color-accent) 12%,transparent) 12% 39%,transparent 42%)}
.oh-deck figure[data-doodle="2"] .oh-flash-face strong span{background:linear-gradient(178deg,transparent 84%,color-mix(in srgb,var(--color-accent) 34%,transparent) 86% 92%,transparent 95%)}
.oh-deck figure[data-doodle="3"] .oh-flash-face strong span{background:linear-gradient(1deg,transparent 6%,color-mix(in srgb,var(--color-accent) 13%,transparent) 9% 76%,transparent 79%)}
.oh-flash-doodle{position:absolute;inset:0;width:100%;height:100%;pointer-events:none;color:var(--color-dim);opacity:.26;fill:none;stroke:currentColor;stroke-width:1.25;stroke-linecap:round;stroke-linejoin:round}
.oh-flash-face p,.oh-flash-face strong,.oh-flash-label{position:relative}

/* Article reading space follows whether a real sidebar exists. */
.content-cards-wrap--article-index>.content-cards{width:min(calc(100% - 2 * var(--page-gutter,24px)),calc(var(--page-max,1120px) - 2 * var(--page-gutter,24px)))}
.post-hero ~ .detail-content-layout:not(.detail-content-layout--has-toc){--content-max:960px;--detail-prose-max:100%}
@media(min-width:769px){
 .post-hero ~ .detail-content-layout:not(.detail-content-layout--has-toc) .detail-content-area p.aup-text{font-size:18px;line-height:1.8}
 .content-cards-wrap--article-index.content-cards-wrap--fleet .card-cover{width:200px;aspect-ratio:3/2}
}
/* A quiet editorial change of pace, using the article's own cover and copy. */
.content-cards-wrap--article-index.content-cards-wrap--fleet .content-card--visual{grid-template-columns:minmax(0,320px) minmax(0,1fr);gap:36px;align-items:center;padding:30px 0;margin:8px 0 16px;background:transparent;border:0;border-block:1px solid var(--color-border);border-radius:0}
.content-cards-wrap--article-index.content-cards-wrap--fleet .content-card--visual .card-cover{width:100%;aspect-ratio:16/10;border-radius:5px;grid-column:1;grid-row:1}
.content-cards-wrap--article-index.content-cards-wrap--fleet .content-card--visual .card-title{font-size:clamp(25px,2.5vw,34px);line-height:1.3}
.content-cards-wrap--article-index.content-cards-wrap--fleet .content-card--visual .card-excerpt{-webkit-line-clamp:3}
@media(max-width:768px){
 .content-cards-wrap--article-index>.content-cards{width:calc(100% - 2 * var(--page-gutter,16px))}
 .content-cards-wrap--article-index.content-cards-wrap--fleet .content-card--visual{grid-template-columns:1fr;padding:24px 0;gap:20px;margin:8px 0 16px}
 .content-cards-wrap--article-index.content-cards-wrap--fleet .content-card--visual .card-cover{grid-row:1}
 .content-cards-wrap--article-index.content-cards-wrap--fleet .content-card--visual .card-title{font-size:25px}
}
/* Event location is atmosphere, using actual geographic tiles. Text stays above it. */
.oh--event{isolation:isolate}.oh--event .oh-inner{position:relative;z-index:1;padding-bottom:64px}
.oh-event-map{position:absolute;inset:0 0 0 22%;overflow:hidden;pointer-events:none;z-index:0;opacity:.32;mask-image:linear-gradient(90deg,transparent,#000 42%,#000 85%,transparent),linear-gradient(0deg,transparent,#000 30%,#000 75%,transparent);mask-composite:intersect}
.oh-map-sheet{position:absolute;width:768px;height:768px;left:50%;top:50%;transform:translate(-50%,-50%) scale(1.55);filter:grayscale(1) contrast(.8);mask-image:radial-gradient(ellipse 250px 250px at center,#000 24%,transparent 100%)}
.oh-map-sheet img{position:absolute;width:256px!important;height:256px!important;max-width:none!important;display:block}
.oh-map-credit{position:absolute;bottom:12px;right:24px;z-index:2;font:10px/1.5 var(--font-body);color:var(--color-dim)}
.oh-map-credit a{color:inherit;text-decoration:none}.oh-map-credit a:hover{text-decoration:underline}
.oh-map-link{display:inline-flex;gap:7px;margin-top:18px;color:var(--color-accent);font:12px/1.5 var(--font-body);text-decoration:none}
.oh--event .oh-date-board{padding:26px 30px;border:1px solid var(--color-border);border-top:3px solid var(--color-accent);border-radius:5px;background:color-mix(in srgb,var(--color-bg) 85%,transparent);box-shadow:0 14px 38px #092c2310;transform:rotate(2deg);position:relative}
.oh--event .oh-date-board::after{content:"";display:block;margin-top:24px;border-top:1px dashed var(--color-border)}
.oh-event-ticket{position:absolute;inset:0;display:flex;flex-direction:column;justify-content:center;gap:16px;padding:30px;background:linear-gradient(130deg,color-mix(in srgb,var(--color-accent) 9%,var(--color-bg)),var(--color-bg));border:1px solid var(--color-border)}
.oh-event-ticket>span{font:12px var(--font-utility);color:var(--color-dim)}.oh-event-ticket strong{font:500 clamp(20px,2.5vw,30px)/1.25 var(--font-display);letter-spacing:-.02em;color:var(--color-text)}.oh-event-ticket small{font:12px var(--font-body);color:var(--color-dim)}
.oh-event-phase{position:absolute;right:12px;top:12px;z-index:2;padding:4px 8px;background:var(--color-bg);color:var(--color-accent);border:1px solid var(--color-border);border-radius:3px;font:10px/1.3 var(--font-body)}
.oh-event-phase[data-phase=past]{color:var(--color-dim)}
@media(prefers-color-scheme:dark){html:not([data-mode=light]) .oh-event-map{opacity:.16}}
[data-mode=dark] .oh-event-map{opacity:.16}
@media(max-width:760px){.oh-event-map{inset:30% -20% 0 0;opacity:.22}.oh--event .oh-inner{padding-bottom:56px}.oh--event .oh-date-board{transform:none;padding:20px 24px}.oh--event .oh-date-board strong{font-size:40px}.oh-event-ticket{padding:25px}.oh-event-ticket strong{font-size:23px}}

.content-cards-wrap--article-index.content-cards-wrap--fleet .content-card--visual .card-body{grid-column:2;grid-row:1}
.content-cards-wrap--fleet .content-card--text{grid-template-columns:minmax(0,1fr)}
@media(max-width:768px){
 .content-cards-wrap--article-index.content-cards-wrap--fleet .content-card{grid-template-columns:minmax(0,1fr);gap:16px}
 .content-cards-wrap--article-index.content-cards-wrap--fleet .card-cover{width:100%;grid-column:1;grid-row:1;aspect-ratio:16/9}
 .content-cards-wrap--article-index.content-cards-wrap--fleet .content-card--visual .card-body{grid-column:1;grid-row:2}
}
/* Event facts sit on the page, rather than inside nested presentation boxes. */
.oh--event .oh-date-board{padding:20px 0 20px 36px;border:0;border-left:1px solid color-mix(in srgb,var(--color-accent) 28%,transparent);border-radius:0;background:transparent;box-shadow:none;transform:none}
.oh--event .oh-date-board::after{display:none}
@media(max-width:760px){.oh--event .oh-date-board{padding:16px 0;border:0;border-top:1px solid var(--color-border)}}
.content-cards-wrap--article-index.content-cards-wrap--fleet .content-card--text{grid-template-columns:minmax(0,1fr)}
.content-cards-wrap--fleet .card-link:focus-visible{outline:none}

/* Terminal panels keep a dark canvas in both site themes. */
.product-frame__terminal .hljs-section { color: #79c0ff; }

/* Off-stack slides need neither painting nor eager image downloads.
   The existing deck controller reveals the next card two turns before it leads. */
.oh-deck figure[data-position="3"] { display: none; }

.site-footer .footer-translation-note { margin: 16px 0 0; max-width: 90ch; color: var(--color-dim, #5d706b); font-size: 12px; line-height: 1.65; word-break: keep-all; overflow-wrap: anywhere; }

.site-footer .footer-attribution { margin-top: 1rem; display: flex; align-items: center; flex-wrap: wrap; gap: .25rem .6rem; }
.site-footer .footer-attribution-dot { color: var(--color-dim, #5d706b); font-size: 12px; }
.site-footer .footer-built-with { display: inline-flex; vertical-align: middle; border-radius: 2px; transition: opacity 140ms ease; }
.site-footer .footer-built-with:hover { opacity: .72; }
.site-footer .footer-built-with:focus-visible { outline: 2px solid var(--color-accent, #008f7a); outline-offset: 5px; }
.site-footer .footer-built-with img { display: block; width: 140px; height: auto; }
.site-footer .footer-built-with .footer-built-dark { display: none; }
html[data-mode=dark] .site-footer .footer-built-light { display: none; }
html[data-mode=dark] .site-footer .footer-built-dark { display: block; }
@media (prefers-reduced-motion: reduce) { .site-footer .footer-built-with { transition: none; } }

.site-footer .footer-built-caption { margin: 0; color: var(--color-dim, #5d706b); font-size: 12px; line-height: 1.65; word-break: keep-all; overflow-wrap: anywhere; }

/* One footer surface: policies sit with navigation; attribution closes the footer. */
.site-footer .footer-grid{align-self:start;padding-top:.4rem}
.site-footer .footer-legal{margin-top:1rem}
.site-footer .footer-legal a{font-size:.78rem}
.site-footer .footer-bottom{align-items:flex-start;flex-direction:column;justify-content:flex-start;text-align:left;gap:.7rem}
.site-footer .footer-bottom .footer-translation-note{margin:0;max-width:none;flex:none;font-size:.73rem}
.site-footer .footer-built-caption a{color:inherit;text-decoration:underline;text-decoration-color:color-mix(in srgb,currentColor 40%,transparent);text-underline-offset:.2em}
.site-footer .footer-built-caption a:hover{color:var(--color-accent)}
@media(max-width:760px){.site-footer .footer-top.has-connection{grid-template-columns:1fr}.site-footer .footer-bottom .footer-translation-note{flex-basis:auto}.site-footer .footer-grid{padding-top:0}}

/* Docs owns its grid placement; these rules give article detail pages the same
   TOC disclosure and active-link vocabulary without coupling either layout. */
.detail-content-sidebar .in-page-toc {
  position: sticky;
  top: 6rem;
  max-height: calc(100vh - 8rem);
  overflow-y: auto;
  padding-left: 1.25rem;
  border-left: 1px solid var(--color-border, #e8e8e8);
}

.detail-content-sidebar .docs-toc-title {
  margin: 0 0 0.8rem;
  color: var(--color-text, #171717);
  font-size: 0.75rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.detail-content-sidebar .docs-toc-toggle {
  display: none;
}

.detail-content-sidebar .docs-toc-list {
  display: flex;
  flex-direction: column;
  gap: 0.2rem;
  margin: 0;
  padding: 0;
  list-style: none;
}

.detail-content-sidebar .docs-toc-link {
  display: block;
  padding: 0.32rem 0;
  color: var(--color-dim, #737373);
  font-size: 0.82rem;
  line-height: 1.45;
  text-decoration: none;
  transition: color 0.15s ease;
}

.detail-content-sidebar .docs-toc-item--h3 .docs-toc-link {
  padding-left: 0.85rem;
  font-size: 0.77rem;
}

.detail-content-sidebar .docs-toc-link:hover,
.detail-content-sidebar .docs-toc-link.is-active {
  color: var(--color-accent, #1e6fd9);
}

.detail-content-sidebar .docs-toc-link.is-active {
  font-weight: 650;
}

@media (max-width: 1100px) {
  .detail-content-sidebar .in-page-toc {
    position: static;
    max-height: none;
    overflow: visible;
    padding: 0;
    border: 1px solid var(--color-border, #e8e8e8);
    border-radius: var(--radius-lg, 8px);
    background: var(--color-surface, #fafafa);
  }

  .detail-content-sidebar .docs-toc-title {
    display: none;
  }

  .detail-content-sidebar .docs-toc-toggle {
    display: flex;
    width: 100%;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    padding: 0.85rem 1rem;
    border: 0;
    background: transparent;
    color: var(--color-text, #171717);
    font: inherit;
    font-size: 0.86rem;
    font-weight: 650;
    text-align: left;
    cursor: pointer;
  }

  .detail-content-sidebar .docs-toc-toggle-icon::before {
    content: "+";
  }

  .detail-content-sidebar .docs-toc-toggle[aria-expanded="true"] .docs-toc-toggle-icon::before {
    content: "−";
  }

  .detail-content-sidebar .docs-toc-list {
    display: none;
    padding: 0 1rem 0.85rem;
  }

  .detail-content-sidebar .in-page-toc.is-open .docs-toc-list {
    display: flex;
  }
}


  /* ── comments-surface widget (issue #1006 Phase 1 + Phase 2) ──
     Flat comment list + composer + per-item edit/delete/react. All
     sizing/color/spacing consumes canonical AUP tokens (styles.ts) so
     theme swaps reach it, same discipline as .aup-list-item / .aup-cb-*. */
  .aup-comments-surface { display: flex; flex-direction: column; gap: var(--space-block); }
  /* arc#2935 item 2: was --type-heading (this widget's mount context has no
     idea what level the host page's own headings sit at) — a live doc page's
     own <h2> renders at 24px (docs-page/style.css .docs-content h2:
     clamp(1.35rem, 1.9vw, 1.5rem)), while --type-heading resolved to 28px in
     that same theme, so this section heading visually OUTRANKED the page's
     real section headings despite now (see the <h2> tag change above) being
     one level below them in the outline. --type-subheading is this token
     family's next tier down (styles.ts) — reliably smaller than
     --type-heading in every density preset, not a hardcoded px guess tied to
     one page's own clamp(). */
  .aup-comments-surface-title {
    font-family: var(--font-heading);
    font-size: var(--type-subheading);
    font-weight: var(--heading-weight);
    color: var(--color-text);
  }
  /* Sort-order toggle (arc#2231) — right-aligned, above the list. */
  .aup-comments-surface-toolbar { display: flex; justify-content: flex-end; }
  .aup-comments-surface-list { display: flex; flex-direction: column; gap: var(--space-element); }
  .aup-comments-surface-empty {
    color: var(--color-dim);
    font-size: var(--type-body);
    padding: var(--space-block) 0;
    text-align: center;
  }
  /* Inline error banner for a failed post/edit/delete/react — hidden by
     default (JS toggles display), shown with a plain error-tinted text
     row (no dialog, matches the low-ceremony feel of an inline form error). */
  .aup-comments-surface-error {
    color: var(--color-error);
    font-size: var(--type-caption);
    padding: 0 0 var(--space-element);
  }
  .aup-comment-item {
    display: flex;
    flex-direction: column;
    gap: var(--space-element);
    padding: var(--space-block);
    background: var(--card-bg);
    border: 1px solid var(--card-border);
    border-radius: var(--radius-md);
  }
  /* arc#2935 item 1: the card's own horizontal padding (--space-block, 18px
     in the measured live theme) pushed the VISIBLE comment text/Reply button
     18px inward from the page's document-content edge on both sides — the
     surrounding page content (and this widget's own unpadded sort toggle,
     which already lands flush) has no such inset, so the comment column
     visibly "broke" out of alignment. Compensating with an equal negative
     horizontal margin cancels the padding for anything measured from the
     card's OUTER edge (so the card border/background still bleeds out to
     the full column width, matching the sort toggle) while the padding
     itself keeps the INNER text sitting exactly where it was — now aligned
     with the page's content edge instead of offset from it.
     Scoped to .aup-comments-surface-list > .aup-comment-item (root-level
     items only, direct children of the list) rather than the bare class:
     a NESTED reply's .aup-comment-item lives inside
     .aup-comment-item-children (module doc "Nested reply-tree
     rendering"), whose own padding-left is the intentional per-depth
     indent — an unscoped negative margin here would cancel that indent too
     and collapse every reply back to the root's left edge. */
  .aup-comments-surface-list > .aup-comment-item {
    margin-left: calc(-1 * var(--space-block));
    margin-right: calc(-1 * var(--space-block));
  }
  .aup-comment-item-header { display: flex; align-items: center; gap: var(--space-element); flex-wrap: wrap; }
  .aup-comment-item-author { font-family: var(--font-body); font-size: var(--type-body); font-weight: var(--heading-weight); color: var(--color-text); }
  .aup-comment-item-time { font-size: var(--type-caption); color: var(--color-dim); }
  .aup-comment-item-edited { font-style: italic; }
  /* Optimistic preview row (arc#2226) — same reduced-opacity "in flight"
     treatment as .aup-comment-item-collect-btn._aup-collect-pending below,
     applied to the whole card instead of one button since this row has no
     server-assigned id yet for any per-affordance state. */
  .aup-comment-item--pending { opacity: 0.6; }
  /* Pushes the kebab menu button to the row's trailing edge without a
     dedicated flex-justify rule on the header (which also needs to wrap
     author + timestamp on narrow widths). */
  .aup-comment-item-spacer { flex: 1 1 auto; }
  .aup-comment-item-text { font-family: var(--font-body); font-size: var(--type-body); line-height: var(--leading-normal); color: var(--color-text); white-space: normal; word-break: break-word; }
  .aup-comment-item-footer { display: flex; align-items: center; gap: var(--space-element); }
  /* Both children are conditional (reactions opt-in, Reply hidden past
     maxDepth/guest-blocked) — an empty footer would otherwise still eat a
     --space-element gap slot in .aup-comment-item's column flex. */
  .aup-comment-item-footer:empty { display: none; }
  /* Kebab/collect buttons reuse list.ts's .aup-list-row-action square
     icon-button chrome — that rule (and its --collect variant tint, plus
     the Edit/Delete popup below) normally comes from css.ts, which is only
     loaded on AUP-hosted pages. A non-AUP host (web-device, issue #2676)
     loads ONLY this COMMENTS_SURFACE_CSS + AUP_PRIMITIVES_CSS, neither of
     which defines them — so on that host these rendered unstyled with the
     browser's default button chrome (arc#2933). Self-contained here (same
     values as css.ts's copy — safe to duplicate, an AUP host loads both and
     the second occurrence is a no-op) so the bundle never depends on a host
     also having loaded css.ts's full AUP-page stylesheet. */
  .aup-comment-item .aup-list-row-action { display: inline-flex; align-items: center; justify-content: center; width: 28px; height: 28px; padding: 0; margin-left: 4px; background: transparent; border: 1px solid transparent; border-radius: var(--radius-sm); color: var(--color-dim); cursor: pointer; opacity: 0; transition: opacity var(--transition), background var(--transition), color var(--transition), border-color var(--transition); flex-shrink: 0; }
  .aup-comment-item .aup-list-row-action svg { width: 14px; height: 14px; }
  .aup-comment-item .aup-list-row-action:hover { background: color-mix(in srgb, var(--color-text) 6%, transparent); color: var(--color-text); }
  .aup-comment-item .aup-list-row-action--collect:hover { background: var(--color-accent-bg); border-color: color-mix(in srgb, var(--color-accent) 30%, transparent); color: var(--color-accent); }
  .aup-comment-item:hover .aup-list-row-action,
  .aup-comment-item-menu-btn:focus-visible,
  .aup-comment-item-collect-btn:focus-visible { opacity: 1; }
  .aup-comment-item-menu-btn { margin-left: 0; }
  /* Edit/Delete popup (_commentsSurfaceOpenItemMenu) — same duplication
     rationale as .aup-list-row-action above; css.ts's copy (shared with
     list.ts's own item menu) never reaches a non-AUP host. */
  .aup-list-item-menu-popup { background: var(--color-surface); border: 1px solid var(--color-border); border-radius: var(--radius-md); box-shadow: var(--shadow-card); min-width: 160px; overflow: hidden; padding: 4px 0; }
  .aup-list-item-menu-item { display: block; width: 100%; padding: var(--space-element) var(--space-block); text-align: left; background: transparent; border: none; color: var(--color-text); font-family: var(--font-body); font-size: var(--type-body); line-height: var(--leading-normal); cursor: pointer; white-space: nowrap; transition: background var(--transition), color var(--transition); }
  .aup-list-item-menu-item:hover { background: color-mix(in srgb, var(--color-text) 7%, transparent); }
  .aup-list-item-menu-item:has(svg) { display: flex; align-items: center; gap: var(--space-element); }
  .aup-list-item-menu-item svg { width: 14px; height: 14px; flex-shrink: 0; }
  /* Collect button (issue #1576) — .aup-list-row-action--collect's hover
     tint already comes from this file's own rule above (arc#2933); the two
     rules below only cover its two extra per-comment states that button
     family doesn't otherwise need: a subtle pulse while the collect
     aup_event is in flight (same idea as reaction.ts's JS-injected
     _aup-reaction-pending keyframes, redeclared here as a plain CSS
     keyframe since this file — not JS — is comments-surface's only style
     source), and staying visibly marked (not fading back to opacity:0 on
     mouseleave) once collected — same "persistent highlight" treatment
     reaction chips give an own-reaction, applied here to a single terminal
     state instead of a toggle. */
  @keyframes aup-comment-collect-pulse { 0%, 100% { box-shadow: 0 0 0 2px transparent; } 50% { box-shadow: 0 0 0 2px var(--color-accent); } }
  .aup-comment-item-collect-btn._aup-collect-pending { animation: aup-comment-collect-pulse 0.9s ease-in-out infinite; opacity: 0.75; }
  .aup-comment-item-collect-btn.is-collected { opacity: 1; color: var(--color-accent); }
  /* Reaction picker placeholder (issue #1626, opt-in via props.reactions —
     see comments-surface-bundle.ts module doc "Reaction picker"). The picker
     element mounted inside it (reaction.ts's _buildReactionPickerEl,
     class .aup-reaction) carries its own inline layout styles already;
     this rule only keeps an empty placeholder from adding stray footer
     gap before the async reaction-data fetch populates it. */
  .aup-comment-item-reactions:empty { display: none; }
  /* Composer — top-level "post a new comment" form. Bordered container in
     the same card-token family as .aup-comment-item so it reads as part
     of the same surface, not a foreign form. */
  .aup-comments-surface-composer {
    display: flex; flex-direction: column; gap: var(--space-element);
    padding: var(--space-block);
    background: var(--card-bg);
    border: 1px solid var(--card-border);
    border-radius: var(--radius-md);
  }
  /* arc#2935 item 1 (composer half): same padding-not-compensated fix as
     .aup-comment-item above, scoped to the top-level "new comment" composer
     only (a direct child of .aup-comments-surface — see _commentsSurfaceBuild)
     — a REPLY composer reuses this same class but is appended inside its
     parent .aup-comment-item (_commentsSurfaceToggleReplyComposer), where it
     is correctly meant to stay inset within the parent card's own padding,
     not bleed to the page edge. */
  .aup-comments-surface > .aup-comments-surface-composer {
    margin-left: calc(-1 * var(--space-block));
    margin-right: calc(-1 * var(--space-block));
  }
  .aup-comments-surface-composer-input,
  .aup-comment-edit-textarea {
    width: 100%; box-sizing: border-box;
    padding: 8px 12px;
    background: var(--color-bg);
    color: var(--color-text);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    font-family: var(--font-body); font-size: var(--type-body); line-height: var(--leading-normal);
    outline: none;
    resize: vertical;
    transition: border-color var(--transition);
  }
  .aup-comments-surface-composer-input::placeholder,
  .aup-comment-edit-textarea::placeholder { color: var(--color-dim); }
  .aup-comments-surface-composer-input:focus,
  .aup-comment-edit-textarea:focus {
    border-color: var(--color-accent);
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--color-accent) 12%, transparent);
  }
  .aup-comments-surface-composer-row { display: flex; justify-content: flex-end; gap: var(--space-element); }
  /* post-editor (issue #1623 round 2): create/edit now mount their form inside
     the shared form-dialog modal (_aupShowFormOverlay, action.ts) instead of an
     always-open inline card, so .aup-post-editor's own composer needs none of
     the card padding/elevation the page-embedded version used to add — the
     dialog body (.aup-view[data-variant="form-dialog-body"]) already supplies
     that chrome. Selector kept (not deleted) so a future non-dialog placement
     of this widget doesn't silently inherit unstyled comment-reply spacing. */
  .aup-post-editor .aup-comments-surface-composer { padding: 0; }
  /* post-editor body Write/Preview toggle (issue #4057 P1 composer 预览
     sub-capability). Reuses the generic .aup-tab-bar/.aup-tab primitive for
     the toggle and .aup-text[data-format="markdown"] for the rendered
     preview's prose styling — no new tab or typography tokens. */
  .aup-post-editor-body-tabs { margin-bottom: var(--space-element); padding: 0; }
  .aup-post-editor-body-preview {
    box-sizing: border-box;
    /* Approximates the textarea's rows=8 height (em-based, not a magic px)
       so toggling Write/Preview doesn't visibly resize the dialog. */
    min-height: 10em;
    padding: 8px 12px;
    background: var(--color-bg);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
  }
  .aup-post-editor-body-preview-empty { color: var(--color-dim); font-size: var(--type-body); }
  .aup-comment-item-edit { display: flex; flex-direction: column; gap: var(--space-element); }
  .aup-comment-item-edit-actions { display: flex; justify-content: flex-end; gap: var(--space-element); }
  /* ── Nested reply-tree (issue #1006 Phase 3) ──
     Indentation compounds purely from DOM nesting: each level wraps the
     next inside another .aup-comment-item-children, so a single
     padding-left naturally produces increasing indent with depth — see
     comments-surface-bundle.ts module doc "Nested reply-tree rendering". */
  .aup-comment-item-children {
    display: flex; flex-direction: column; gap: var(--space-element);
    margin-top: var(--space-element);
    padding-left: var(--space-block);
    border-left: 1px solid var(--card-border);
  }
  /* arc#2933 follow-up (issuecomment-5163252813): no own margin-left here —
     .aup-comment-item-footer already spaces its children via its flex gap
     (same pattern .aup-comment-item-header uses above). A redundant
     margin-left on this button double-spaced it when a reactions picker
     precedes it, and — worse — pushed Reply off the card's own left edge
     whenever it's the footer's ONLY child (reactions disabled, or the
     reaction placeholder collapsed via :empty). Left-alignment must come
     from the footer's own flex layout, not a per-button margin assuming a
     preceding sibling always exists. */
  .aup-comment-reply-btn {
    display: inline-flex; align-items: center;
    padding: 2px var(--space-element);
    background: transparent;
    border: 1px solid var(--card-border);
    border-radius: var(--radius-sm);
    color: var(--color-dim);
    /* A <button> does not inherit the page font by default (browser UA
       stylesheet), so without this it renders in the platform's default
       UI font (observed as Arial on arc#2933) instead of the site's
       Inter/Noto Sans SC — every other text in this widget already goes
       through _escapeHtml'd content inside a font-family: var(--font-body)
       ancestor (.aup-comment-item-text etc.), only this <button> was left
       on the UA default. */
    font-family: var(--font-body);
    font-size: var(--type-caption);
    cursor: pointer;
    transition: background var(--transition), border-color var(--transition), color var(--transition);
  }
  .aup-comment-reply-btn:hover { background: var(--hover-bg); color: var(--color-text); }
  .aup-comment-reply-composer { padding-top: var(--space-element); }
  /* Guest display-name field (Phase 3 anonymous posting) — same input
     chrome as the composer textarea, single line. */
  .aup-comments-surface-composer-name {
    width: 100%; box-sizing: border-box;
    padding: 8px 12px;
    background: var(--color-bg);
    color: var(--color-text);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    font-family: var(--font-body); font-size: var(--type-body);
    outline: none;
    transition: border-color var(--transition);
  }
  .aup-comments-surface-composer-name::placeholder { color: var(--color-dim); }
  .aup-comments-surface-composer-name:focus {
    border-color: var(--color-accent);
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--color-accent) 12%, transparent);
  }
  /* Guest gating (issue #1514) — same card chrome as the composer it
     replaces, so the surface doesn't visually jump when requireAuth flips
     the guest UX from a full form to a read-only prompt. */
  .aup-comments-surface-login-prompt {
    margin-left: calc(-1 * var(--space-block));
    margin-right: calc(-1 * var(--space-block));
    padding: var(--space-block);
    background: var(--card-bg);
    border: 1px solid var(--card-border);
    border-radius: var(--radius-md);
    color: var(--color-dim);
    font-size: var(--type-body);
  }

/* comments-surface — host-side layout only (arc#2676).
 *
 * The thread's OWN styling ships with the renderer, in the shared
 * COMMENTS_SURFACE_CSS the `comments-surface-runtime` enhancement injects
 * (issue #2675 extracted it out of css.ts so AUP pages and this page consume
 * one source). Nothing in that sheet is restated here — this file only
 * positions the mount point in the page flow and styles the one state the
 * shared renderer has no concept of: a host transport failure.
 *
 * Every value is a canonical AUP token (providers/runtime/ui/CLAUDE.md rule 1).
 * Pre-rendered pages already embed the full primitives sheet (EPIC #2672 fact
 * 7), so the tokens resolve here exactly as they do inside /app.
 */

.comments-surface {
  margin-top: var(--space-section);
  /* A real layout box before the thread loads. The section is emitted EMPTY
     and, deliberately, NOT `hidden` — `display:none` has no box, and an
     element with no box never intersects, so the IntersectionObserver that
     triggers the lazy fetch would never fire. 1px is invisible to a reader
     and is also what a JS-disabled visitor is left with: an empty band, no
     skeleton residue. */
  min-height: 1px;
}

.comments-surface-error {
  display: flex;
  align-items: center;
  gap: var(--space-element);
  padding: var(--space-block);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  background: var(--color-surface);
  color: var(--color-dim);
  font-size: var(--type-caption);
  line-height: var(--leading-normal);
}

.comments-surface-retry {
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--color-text);
  font: inherit;
  /* No canonical token for a control's own height/padding — see rule 4's
     "touch-target heights" carve-out; kept on the spacing scale where it can
     be. */
  padding: 0.25rem var(--space-element);
  cursor: pointer;
  transition: var(--transition);
}

.comments-surface-retry:hover {
  background: var(--hover-bg);
}

[data-media-lightbox] .media-lightbox-figure {
  max-width: 100%;
  margin: 1.4rem 0;
}

[data-media-lightbox] .media-lightbox-trigger {
  display: block;
  max-width: 100%;
  padding: 0;
  border: 0;
  background: transparent;
  cursor: zoom-in;
}

[data-media-lightbox] .media-lightbox-trigger:focus-visible {
  border-radius: var(--radius-lg, 8px);
  outline: 3px solid var(--color-accent, #1e6fd9);
  outline-offset: 4px;
}

[data-media-lightbox] .media-lightbox-figure img {
  display: block;
  max-width: 100%;
  height: auto;
  margin: 0;
}

[data-media-lightbox][data-media-breakout] .media-lightbox-figure {
  width: min(var(--media-breakout-max, var(--container-max, 1280px)), calc(100vw - 2rem));
  max-width: min(var(--media-breakout-max, var(--container-max, 1280px)), calc(100vw - 2rem));
  margin: 1.75rem 50%;
  transform: translateX(-50%);
}

[data-media-lightbox][data-media-breakout] .media-lightbox-trigger {
  width: 100%;
}

[data-media-lightbox][data-media-breakout] .media-lightbox-figure img {
  width: auto;
  margin: 0 auto;
  border: 1px solid color-mix(in srgb, var(--color-border, #e8e8e8) 78%, transparent);
}

[data-media-lightbox] .media-lightbox-caption {
  max-width: var(--content-max, 820px);
  margin: 0.75rem auto 0;
  color: var(--color-dim, #737373);
  font-size: 0.88rem;
  line-height: 1.5;
  text-align: center;
}

.media-lightbox[hidden] {
  display: none;
}

.media-lightbox {
  position: fixed;
  z-index: 1000;
  inset: 0;
  display: grid;
  place-items: center;
  padding: clamp(1rem, 4vw, 3rem);
  border: 0;
  background: color-mix(in srgb, #000 88%, transparent);
  animation: media-lightbox-fade-in 180ms ease-out;
}

.media-lightbox img {
  max-width: 100%;
  max-height: calc(100vh - 6rem);
  object-fit: contain;
  animation: media-lightbox-image-in 220ms cubic-bezier(0.22, 1, 0.36, 1);
}

.media-lightbox-close {
  position: fixed;
  top: 1rem;
  right: 1rem;
  display: grid;
  width: 2.75rem;
  height: 2.75rem;
  place-items: center;
  border: 1px solid rgb(255 255 255 / 45%);
  border-radius: 999px;
  background: rgb(0 0 0 / 55%);
  color: #fff;
  font-size: 1.5rem;
  cursor: pointer;
}

.media-lightbox-close:focus-visible {
  outline: 3px solid #fff;
  outline-offset: 3px;
}

body.media-lightbox-open {
  overflow: hidden;
}

@keyframes media-lightbox-fade-in {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}

@keyframes media-lightbox-image-in {
  from {
    opacity: 0;
    transform: scale(0.98);
  }
  to {
    opacity: 1;
    transform: scale(1);
  }
}

@media (prefers-reduced-motion: reduce) {
  .media-lightbox,
  .media-lightbox img {
    animation: none;
  }
}

@media (max-width: 768px) {
  [data-media-lightbox][data-media-breakout] .media-lightbox-figure {
    width: calc(100vw - 2rem);
    max-width: calc(100vw - 2rem);
  }
}

/* docs-page — Mintlify-style docs layout.
   Two columns: sidebar nav + prose content.
   Inherits site tokens: --color-bg / --color-text / --color-accent / --font-display / --font-body / --font-mono. */

.docs-shell {
  --docs-sidebar: 280px;
  --docs-content: 760px;
  --docs-rule: color-mix(in srgb, var(--color-border, #e5e7eb) 55%, transparent);
  --docs-rule-soft: color-mix(in srgb, var(--color-border, #e5e7eb) 35%, transparent);
  --docs-muted: color-mix(in srgb, var(--color-dim, #6b7280) 88%, var(--color-text, #0f172a));
  --docs-soft-bg: color-mix(
    in srgb,
    var(--color-accent, #2563eb) 5%,
    var(--color-surface, #fafafa)
  );

  width: 100%;
  max-width: var(--page-max);
  margin: 0 auto;
  padding: clamp(2rem, 4vw, 3.5rem) var(--page-gutter) clamp(4rem, 8vw, 7rem);
  box-sizing: border-box;
  display: grid;
  grid-template-columns: var(--docs-sidebar) minmax(0, 1fr);
  gap: clamp(2.5rem, 5vw, 4rem);
  color: var(--color-text, #0f172a);
}

@media (min-width: 961px) {
  .docs-shell {
    grid-template-columns: minmax(220px, 240px) minmax(0, 1fr);
    gap: clamp(2rem, 3vw, 2.5rem);
  }
}

/* ── Sidebar ──────────────────────────────────────── */

.docs-sidebar {
  position: sticky;
  top: 96px;
  align-self: start;
  max-height: calc(100vh - 120px);
  padding-right: 0.75rem;
  overflow-y: auto;
  scrollbar-width: thin;
}

.docs-sidebar-brand {
  display: inline-flex;
  align-items: center;
  gap: 0.55rem;
  margin-bottom: 1.6rem;
  color: var(--color-text, #0f172a);
  font-family: var(--font-display, "Sora", system-ui, sans-serif);
  font-size: 1rem;
  font-weight: 460;
  letter-spacing: -0.005em;
  text-decoration: none;
}

.docs-sidebar-brand:hover {
  color: var(--color-accent, #2563eb);
}

.docs-sidebar-mark {
  display: inline-block;
  width: 0.7rem;
  height: 0.7rem;
  border-radius: 2px;
  background: linear-gradient(
    135deg,
    var(--color-accent, #2563eb),
    var(--color-accent-secondary, var(--color-accent, #2563eb))
  );
}

.docs-sidebar-nav {
  display: flex;
  flex-direction: column;
  gap: 1.4rem;
}

.docs-nav-group-label {
  margin: 0 0 0.75rem;
  padding-left: 0.7rem;
  color: var(--color-dim, #6b7280);
  font-family: var(--font-mono, "JetBrains Mono", ui-monospace, monospace);
  font-size: 0.68rem;
  font-weight: 500;
  letter-spacing: 0.18em;
  text-transform: uppercase;
}

.docs-nav-list {
  display: flex;
  flex-direction: column;
  gap: 0.05rem;
}

.docs-nav-link {
  display: block;
  padding: 0.45rem 0.7rem;
  border-left: 2px solid transparent;
  margin-left: -2px;
  color: var(--docs-muted);
  font-family: var(--font-body, "Inter", system-ui, sans-serif);
  font-size: 0.9rem;
  font-weight: 440;
  text-decoration: none;
  letter-spacing: -0.005em;
  transition:
    color 0.18s ease,
    border-color 0.18s ease,
    background 0.18s ease;
}

.docs-nav-link:hover {
  color: var(--color-text, #0f172a);
  background: color-mix(in srgb, var(--color-accent, #2563eb) 5%, transparent);
}

.docs-nav-link.is-active {
  color: var(--color-accent, #2563eb);
  border-left-color: var(--color-accent, #2563eb);
  font-weight: 500;
}

/* ── Recursive `_nav.yaml` sidebar tree (arc#2436 Phase 4) ─── */
/* Same `.docs-sidebar-nav` container, same mobile drawer toggle as the flat
   sections nav above — this only changes what's inside it when a collection
   has a `_nav.yaml`. */

.docs-nav-tree,
.docs-nav-tree-children {
  display: flex;
  flex-direction: column;
  gap: 0.05rem;
  margin: 0;
  padding: 0;
  list-style: none;
}

.docs-nav-tree-children {
  padding-left: 0.9rem;
  margin-top: 0.05rem;
}

.docs-nav-tree-children[hidden] {
  display: none;
}

.docs-nav-tree-row {
  display: flex;
  align-items: stretch;
}

.docs-nav-tree-row .docs-nav-tree-link {
  flex: 1;
}

.docs-nav-tree-toggle {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  padding: 0.45rem 0.5rem;
  border: 0;
  background: transparent;
  color: var(--docs-muted);
  font-family: var(--font-body, "Inter", system-ui, sans-serif);
  cursor: pointer;
}

.docs-nav-tree-toggle--group {
  width: 100%;
  justify-content: space-between;
  padding: 0.45rem 0.7rem;
  border-left: 2px solid transparent;
  margin-left: -2px;
  font-size: 0.68rem;
  font-weight: 500;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

.docs-nav-tree-toggle:hover {
  color: var(--color-text, #0f172a);
}

.docs-nav-tree-toggle-icon {
  flex-shrink: 0;
  width: 0.55rem;
  height: 0.55rem;
  border-right: 1.5px solid currentColor;
  border-bottom: 1.5px solid currentColor;
  transform: rotate(-45deg);
  transition: transform 0.15s ease;
}

.docs-nav-tree-toggle[aria-expanded="true"] .docs-nav-tree-toggle-icon {
  transform: rotate(45deg);
}

/* ── Mobile nav drawer toggle (hidden on desktop; arc#2303) ─── */

.docs-nav-toggle {
  display: none;
}

.docs-nav-close,
.docs-toc-toggle {
  display: none;
}

.docs-nav-backdrop {
  display: none;
  position: fixed;
  inset: 0;
  z-index: 20;
  background: color-mix(in srgb, #000 45%, transparent);
}

/* ── Main column ──────────────────────────────────── */

.docs-main {
  min-width: 0;
  max-width: var(--docs-content);
}

/* Collection landing pages are navigation surfaces, not prose. Let their
   entry-card grid consume the full main column so its right edge aligns with
   the shared header container. Detail pages keep the readable prose width. */
.docs-main:has(.docs-entry-groups) {
  max-width: none;
}

.docs-body {
  min-width: 0;
}

.docs-detail-layout {
  min-width: 0;
}

/* ── In-page TOC ("On this page") ────────────────── */

.docs-toc {
  position: sticky;
  top: 96px;
  align-self: start;
  max-height: calc(100vh - 120px);
  overflow-y: auto;
  scrollbar-width: thin;
}

.docs-toc-title {
  margin: 0 0 0.75rem;
  color: var(--color-dim, #6b7280);
  font-family: var(--font-mono, "JetBrains Mono", ui-monospace, monospace);
  font-size: 0.68rem;
  font-weight: 500;
  letter-spacing: 0.16em;
  text-transform: uppercase;
}

.docs-toc-list {
  display: flex;
  flex-direction: column;
  gap: 0.05rem;
  margin: 0;
  padding: 0;
  list-style: none;
  border-left: 1px solid var(--docs-rule-soft);
}

.docs-toc-link {
  display: block;
  padding: 0.32rem 0 0.32rem 0.85rem;
  margin-left: -1px;
  border-left: 2px solid transparent;
  color: var(--docs-muted);
  font-family: var(--font-body, "Inter", system-ui, sans-serif);
  font-size: 0.86rem;
  line-height: 1.4;
  text-decoration: none;
  transition:
    color 0.15s ease,
    border-color 0.15s ease;
}

.docs-toc-item--h3 .docs-toc-link {
  padding-left: 1.3rem;
  font-size: 0.82rem;
}

.docs-toc-link:hover {
  color: var(--color-text, #0f172a);
}

.docs-toc-link.is-active {
  color: var(--color-accent, #2563eb);
  border-left-color: var(--color-accent, #2563eb);
  font-weight: 500;
}

/* Detail pages preserve the full prose measure on wide screens.
   The page-level grid starts the TOC beside the heading, then lets it span the
   article and pager rows in the unused space to the right of the container. */
@media (min-width: 1480px) {
  .docs-main:has(.docs-detail-layout--has-toc) {
    width: 100%;
    max-width: var(--docs-content);
  }

  .docs-detail-layout--has-toc {
    display: grid;
    width: calc(100% + 2.5rem + var(--docs-toc-width, 200px));
    grid-template-columns: minmax(0, var(--docs-content)) var(--docs-toc-width, 200px);
    column-gap: 2.5rem;
    align-items: start;
  }

  .docs-detail-layout--has-toc > .docs-heading {
    grid-column: 1;
    grid-row: 1;
  }

  .docs-detail-layout--has-toc > .docs-body {
    grid-column: 1;
    grid-row: 2;
  }

  .docs-detail-layout--has-toc > .docs-toc {
    grid-column: 2;
    grid-row: 1 / span 3;
  }

  .docs-detail-layout--has-toc > .docs-pager {
    grid-column: 1;
    grid-row: 3;
  }
}

/* At intermediate desktop widths there is room for the navigation sidebar
   and the prose column, but not a third persistent rail. Reuse the existing
   accessible disclosure instead of squeezing the article. */
@media (min-width: 961px) and (max-width: 1479px) {
  .docs-main:has(.docs-detail-layout--has-toc) {
    width: 100%;
    max-width: var(--docs-content);
  }

  .docs-detail-layout--has-toc {
    display: grid;
    grid-template-columns: minmax(0, var(--docs-content));
  }

  .docs-detail-layout--has-toc > .docs-heading {
    grid-row: 1;
  }

  .docs-detail-layout--has-toc > .docs-toc {
    grid-row: 2;
    margin-bottom: 1rem;
    position: static;
    max-height: none;
    padding: 0;
    overflow: visible;
    background: transparent;
  }

  .docs-detail-layout--has-toc > .docs-body {
    grid-row: 3;
  }

  .docs-detail-layout--has-toc > .docs-pager {
    grid-row: 4;
  }
}

@media (max-width: 1479px) {
  .docs-toc-title {
    display: none;
  }

  .docs-toc-toggle {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
    width: 100%;
    padding: 0.75rem 0.9rem;
    border: 1px solid var(--docs-rule);
    border-radius: 8px;
    background: var(--color-surface, #fafafa);
    color: var(--color-text, #0f172a);
    font-family: var(--font-body, "Inter", system-ui, sans-serif);
    font-size: 0.9rem;
    font-weight: 500;
    text-align: left;
    cursor: pointer;
  }

  .docs-toc-toggle-icon {
    width: 0.55rem;
    height: 0.55rem;
    flex-shrink: 0;
    border-right: 2px solid currentColor;
    border-bottom: 2px solid currentColor;
    transform: rotate(45deg);
    transition: transform 0.18s ease;
  }

  .docs-toc-toggle[aria-expanded="true"] .docs-toc-toggle-icon {
    transform: rotate(-135deg);
  }

  .docs-toc-list {
    display: none;
    margin-top: 0.5rem;
    padding: 0.45rem;
    border: 1px solid var(--docs-rule-soft);
    border-radius: 8px;
    background: var(--color-surface, #fafafa);
  }

  .docs-toc.is-open .docs-toc-list {
    display: flex;
  }
}

/* arc#2450: wraps the breadcrumb + the mobile drawer
   toggle in one row, so the two no longer stack as separate pre-content
   rows on mobile. Also rendered (with only the breadcrumb visible) above
   the 960px breakpoint since the toggle is hidden there regardless of which
   container it lives in — this rule is deliberately unscoped so it doesn't
   need a matching desktop override. */
.docs-entry-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
}

.docs-breadcrumb {
  display: flex;
  align-items: center;
  gap: 0.55rem;
  margin: 0 0 1.5rem;
  color: var(--color-dim, #6b7280);
  font-family: var(--font-mono, "JetBrains Mono", ui-monospace, monospace);
  font-size: 0.7rem;
  font-weight: 500;
  letter-spacing: 0.16em;
  text-transform: uppercase;
}

.docs-breadcrumb a {
  color: inherit;
  text-decoration: none;
  transition: color 0.18s ease;
}

.docs-breadcrumb a:hover {
  color: var(--color-accent, #2563eb);
}

.docs-breadcrumb span[aria-hidden] {
  opacity: 0.45;
  letter-spacing: 0;
}

.docs-heading {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 1rem;
  margin: 0 0 2rem;
  padding-bottom: 1.6rem;
  border-bottom: 1px solid var(--docs-rule);
}

.docs-heading-main {
  min-width: 0;
  flex: 1 1 auto;
}

.docs-heading-actions {
  display: flex;
  align-items: center;
  gap: 0.35rem;
  flex: 0 0 auto;
  flex-wrap: wrap;
}

/* arc#2452: brief visual confirmation for Copy page / Copy link (icon-only
   buttons — no visible text label to swap, unlike code-copy.ts's inline code
   copy button), paired with the aria-live announcement in script.js for
   assistive tech. */
.docs-heading-actions .aup-app-header-action.is-success {
  color: var(--color-success, #22c55e);
}
.docs-heading-actions .aup-app-header-action.is-error {
  color: var(--color-error, #ef4444);
}

/* Same visually-hidden pattern as portal-header/style.css's
   `.visually-hidden` — this component doesn't share that file, so it's
   mirrored here for the aria-live copy-status region (script.js). */
.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

.docs-eyebrow {
  margin: 0 0 0.7rem;
  display: inline-flex;
  align-items: center;
  gap: 0.55rem;
  color: var(--color-accent, #2563eb);
  font-family: var(--font-mono, "JetBrains Mono", ui-monospace, monospace);
  font-size: 0.7rem;
  font-weight: 500;
  letter-spacing: 0.18em;
  text-transform: uppercase;
}

.docs-eyebrow::before {
  content: "";
  width: 1.4rem;
  height: 1px;
  background: currentColor;
  opacity: 0.6;
}

.docs-title {
  margin: 0;
  color: var(--color-text, #0f172a);
  font-family: var(--font-display, "Sora", system-ui, sans-serif);
  font-size: clamp(1.875rem, 3.2vw, 2.5rem);
  font-weight: 500;
  line-height: 1.06;
  letter-spacing: -0.018em;
}

.docs-summary {
  margin: 1rem 0 0;
  max-width: 38rem;
  color: var(--docs-muted);
  font-family: var(--font-body, "Inter", system-ui, sans-serif);
  font-size: 1.125rem;
  font-weight: 400;
  line-height: 1.7;
}

/* ── Prose content ───────────────────────────────── */

/* Intrinsic content — a wide GFM table or a long unbroken code line — must
   shrink inside the detail layout instead of forcing the whole page to scroll.
   min-width: 0 removes the content-based automatic minimum size; max-width:
   100% keeps this column within its container regardless of display mode. */
.docs-content {
  min-width: 0;
  max-width: 100%;
  color: var(--color-text, #0f172a);
  font-family: var(--font-body, "Inter", system-ui, sans-serif);
  font-size: 1rem;
  line-height: 1.78;
}

/* AUP's root view is a flex column with its own block gap. Docs prose already
   owns vertical rhythm through semantic margins on paragraphs, headings,
   lists, media, code, and callouts; keeping both makes consecutive paragraph
   spacing add up to roughly 36px. Remove only the article root's
   generic gap so nested AUP components retain their intended layout. */
.docs-content > .aup-view {
  gap: 0;
}

.docs-content > .aup-text:first-child,
.docs-content > p:first-child {
  margin-top: 0;
}

/* Markdown-authored img/video can carry any intrinsic size — constrain to the
   prose column so a wide screenshot or embed can't push .docs-main into
   horizontal scroll (arc#2301). Gallery tiles live under .aup-media-gallery and
   own their own gap — do not add prose image margins there (they stack into
   huge inter-tile whitespace, especially in masonry columns). */
.docs-content img,
.docs-content video {
  display: block;
  max-width: 100%;
  height: auto;
  margin: 1.4rem 0;
  border-radius: 8px;
}
.docs-content .aup-media-gallery img,
.docs-content .aup-media-gallery video {
  margin: 0;
  border-radius: 0;
}

.docs-content p,
.docs-content .aup-text {
  margin: 0 0 1.1rem;
  color: color-mix(in srgb, var(--color-text, #0f172a) 88%, var(--docs-muted));
}

/* arc#2456 Phase 1: prose gets an explicit font-weight instead of relying on
   an unset cascade (body → .docs-content had no font-weight anywhere in the
   chain — see style.css history / document-css.ts:12 — so the rendered
   weight depended on the loaded variable font's default instance, which is
   exactly how "text reads too light" bugs happen with no single owner).

   arc#2456 Phase 2 correction: Phase 1's comment claimed this rule "can
   never cascade into code/table/blockquote/admonition text", but that
   wasn't actually true — `renderQuote()`/`renderCode()`
   (renderer/primitives/text.ts:137,148,161) put a bare `aup-text` class on
   the `<pre>` code-block wrapper, the `<blockquote>` element, and the
   admonition `<div>` themselves (it's a generic AUP-primitive marker, not a
   "plain paragraph" marker), and the selector list included the bare
   `.docs-content` container too, which leaked via inheritance into any
   descendant with no `font-weight` of its own (inline `<code>`, `<td>`).
   Both matches happened to still compute to 400 (browser initial value),
   so there was no visible regression, but the isolation the comment/tests
   asserted was accidental, not structural. Dropping the bare `.docs-content`
   selector and excluding `pre`/`blockquote`/`.aup-admonition` from the
   `.aup-text` match makes the isolation real: those elements keep whatever
   font-weight their own rules below declare (or the browser default),
   independent of any future change to this rule's value. */
.docs-content p,
.docs-content .aup-text:not(pre):not(blockquote):not(.aup-admonition),
.docs-content ul,
.docs-content ol,
.docs-content li {
  font-weight: 400;
}

.docs-content h2,
.docs-content h2.aup-text {
  margin: 2.6rem 0 0.85rem;
  padding-top: 0;
  border-top: 0;
  color: var(--color-text, #0f172a);
  font-family: var(--font-display, "Sora", system-ui, sans-serif);
  font-size: clamp(1.35rem, 1.9vw, 1.5rem);
  font-weight: 500;
  line-height: 1.18;
  letter-spacing: -0.01em;
  /* arc#2386: portal-header is sticky — without this, a TOC/anchor jump
     lands the heading right under (partly hidden by) the header. */
  scroll-margin-top: 96px;
}

.docs-content h3,
.docs-content h3.aup-text {
  margin: 1.9rem 0 0.6rem;
  color: var(--color-text, #0f172a);
  font-family: var(--font-display, "Sora", system-ui, sans-serif);
  font-size: clamp(1.15rem, 1.7vw, 1.32rem);
  font-weight: 480;
  line-height: 1.24;
  letter-spacing: -0.005em;
  scroll-margin-top: 96px;
}

.docs-content h4,
.docs-content h4.aup-text {
  margin: 1.6rem 0 0.4rem;
  color: var(--color-text, #0f172a);
  font-family: var(--font-display, "Sora", system-ui, sans-serif);
  font-size: 1.06rem;
  font-weight: 500;
}

.docs-content a,
.docs-content .aup-text a {
  color: var(--color-accent, #2563eb);
  text-decoration: none;
  background-image: linear-gradient(0deg, currentColor 0 0);
  background-size: 100% 1px;
  background-position: 0 100%;
  background-repeat: no-repeat;
  transition: background-size 0.2s ease;
}

.docs-content a:hover {
  background-size: 100% 1.4px;
}

.docs-content ul,
.docs-content ol {
  margin: 0 0 1.2rem;
  padding-left: 1.4rem;
  color: color-mix(in srgb, var(--color-text, #0f172a) 88%, var(--docs-muted));
}

.docs-content li {
  margin: 0.35rem 0;
}

.docs-content code,
.docs-content .aup-text code {
  padding: 0.12rem 0.42rem;
  border-radius: 5px;
  background: color-mix(in srgb, var(--color-accent, #2563eb) 10%, var(--color-surface, #fafafa));
  border: 1px solid color-mix(in srgb, var(--color-border, #e5e7eb) 50%, transparent);
  font-family: var(--font-mono, "JetBrains Mono", ui-monospace, monospace);
  font-size: 0.86em;
  color: var(--color-text, #0f172a);
}

/* arc#2392: fenced code blocks get a toolbar (language label + copy button)
   wrapping the <pre> — inline code (single backtick) is untouched. */
.docs-content .aup-code-block {
  margin: 1.4rem 0;
}

.docs-content pre,
.docs-content pre.aup-text {
  margin: 0;
  padding: 1.1rem 1.25rem;
  border: 1px solid var(--docs-rule);
  border-radius: 10px;
  background: var(--color-surface, #fafafa);
  font-family: var(--font-mono, "JetBrains Mono", ui-monospace, monospace);
  font-size: 0.86rem;
  line-height: 1.6;
  overflow-x: auto;
}

.docs-content .aup-code-block .aup-code-toolbar + pre,
.docs-content .aup-code-block .aup-code-toolbar + pre.aup-text {
  border-top-left-radius: 0;
  border-top-right-radius: 0;
}

.docs-content pre code,
.docs-content pre.aup-text code {
  padding: 0;
  border: 0;
  background: transparent;
  font-size: inherit;
}

.docs-content .aup-code-toolbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.6rem;
  padding: 0.5rem 1.1rem;
  border: 1px solid var(--docs-rule);
  border-bottom: 0;
  border-top-left-radius: 10px;
  border-top-right-radius: 10px;
  background: color-mix(in srgb, var(--color-accent, #2563eb) 4%, var(--color-surface, #fafafa));
}

.docs-content .aup-code-lang {
  color: var(--color-dim, #6b7280);
  font-family: var(--font-mono, "JetBrains Mono", ui-monospace, monospace);
  font-size: 0.7rem;
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}

.docs-content .aup-code-copy-btn {
  margin-left: auto;
  padding: 0.3rem 0.65rem;
  border: 1px solid var(--docs-rule);
  border-radius: 6px;
  background: var(--color-surface, #fafafa);
  color: var(--color-dim, #6b7280);
  font-family: var(--font-body, "Inter", system-ui, sans-serif);
  font-size: 0.76rem;
  cursor: pointer;
  transition:
    color 0.15s ease,
    border-color 0.15s ease,
    background 0.15s ease;
}

.docs-content .aup-code-copy-btn:hover {
  color: var(--color-text, #0f172a);
  border-color: color-mix(in srgb, var(--color-accent, #2563eb) 40%, var(--docs-rule));
}

.docs-content .aup-code-copy-btn:focus-visible {
  outline: 2px solid var(--color-accent, #2563eb);
  outline-offset: 2px;
}

.docs-content .aup-code-copy-btn.is-success {
  color: #16a34a;
  border-color: #16a34a;
}

.docs-content .aup-code-copy-btn.is-error {
  color: #dc2626;
  border-color: #dc2626;
}

.docs-content blockquote,
.docs-content blockquote.aup-text {
  margin: 1.4rem 0;
  padding: 1rem 1.25rem;
  border-left: 3px solid var(--color-accent, #2563eb);
  border-radius: 0 10px 10px 0;
  background: var(--docs-soft-bg);
  color: color-mix(in srgb, var(--color-text, #0f172a) 88%, var(--docs-muted));
  font-style: normal;
}

.docs-content blockquote > p:last-child,
.docs-content blockquote .aup-text:last-child {
  margin-bottom: 0;
}

/* GFM alert blocks (`> [!WARNING]` etc, arc#2302) — same shape as a plain
   blockquote plus a colored left border + uppercase type label per intent. */
.docs-content .aup-admonition {
  margin: 1.4rem 0;
  padding: 1rem 1.25rem;
  border-left: 3px solid var(--docs-admonition-color, var(--color-accent, #2563eb));
  border-radius: 0 10px 10px 0;
  background: var(--docs-soft-bg);
  color: color-mix(in srgb, var(--color-text, #0f172a) 88%, var(--docs-muted));
  /* arc#2451 验收标准: 长 URL/code 在窄视口下局部 containment，不撑破容器。
     同 detail-content/style.css 里 `.aup-text` 已用的属性，此前 docs-page 里
     admonition 容器没有对应规则。 */
  max-width: 100%;
  overflow-wrap: anywhere;
}

.docs-content .aup-admonition > p:last-child {
  margin-bottom: 0;
}

.docs-content .aup-admonition-title {
  margin: 0 0 0.35rem;
  color: var(--docs-admonition-color, var(--color-accent, #2563eb));
  font-family: var(--font-mono, "JetBrains Mono", ui-monospace, monospace);
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  /* arc#2451 Phase 3: icon + label, non-color intent differentiation. */
  display: flex;
  align-items: center;
  gap: 0.4rem;
}

.docs-content .aup-admonition-icon {
  width: 14px;
  height: 14px;
  flex: none;
}

.docs-content .aup-admonition[data-intent="note"] {
  --docs-admonition-color: #2563eb;
}

/* arc#2451 验收标准 2 — light-mode contrast fix. Phase 3 measured and fixed
   dark-mode contrast (see the block below) but never re-checked light mode
   against the real light tokens (tokens.json: accent #1E6FD9, surface
   #FAFAFA → --docs-soft-bg ≈ #eff3f8). Measured with the same WCAG formula:
   tip 2.96:1, warning 2.86:1, caution 4.33:1 — all below AA text's 4.5:1
   (note 4.64:1 and important 5.11:1 already passed, left unchanged). Darkened
   along each color's own hue/saturation (not a hue shift) to ~4.6-4.7:1. */
.docs-content .aup-admonition[data-intent="tip"] {
  --docs-admonition-color: #117d39;
}

.docs-content .aup-admonition[data-intent="important"] {
  --docs-admonition-color: #7c3aed;
}

.docs-content .aup-admonition[data-intent="warning"] {
  --docs-admonition-color: #a55a05;
}

.docs-content .aup-admonition[data-intent="caution"] {
  --docs-admonition-color: #d52222;
}

/* arc#2451 Phase 3 — dark-mode contrast fix. Measured against the real
   dark-token values (tokens.json's "dark" section) mixed into
   `--docs-soft-bg`: note/important/caution's light-mode hex values compute
   to 2.97–3.51:1 against that background (WCAG AA text needs 4.5:1;
   tip/warning already measure 5.14/5.32:1 and are left unchanged). Same
   selector pattern `design-tokens.ts`'s `buildSiteTokenCSS` uses for every
   other dark-mode override in this site (`[data-tone][data-palette]` +
   `data-mode`/`prefers-color-scheme`), not the unrelated `page-sections`
   component's own `[data-theme]` convention. */
[data-tone][data-palette][data-mode="dark"] .docs-content .aup-admonition[data-intent="note"] {
  --docs-admonition-color: #5686ef;
}

[data-tone][data-palette][data-mode="dark"] .docs-content .aup-admonition[data-intent="important"] {
  --docs-admonition-color: #a070f2;
}

[data-tone][data-palette][data-mode="dark"] .docs-content .aup-admonition[data-intent="caution"] {
  --docs-admonition-color: #e55b5b;
}

@media (prefers-color-scheme: dark) {
  [data-tone][data-palette]:not([data-mode="light"])
    .docs-content
    .aup-admonition[data-intent="note"] {
    --docs-admonition-color: #5686ef;
  }

  [data-tone][data-palette]:not([data-mode="light"])
    .docs-content
    .aup-admonition[data-intent="important"] {
    --docs-admonition-color: #a070f2;
  }

  [data-tone][data-palette]:not([data-mode="light"])
    .docs-content
    .aup-admonition[data-intent="caution"] {
    --docs-admonition-color: #e55b5b;
  }
}

.docs-content hr {
  margin: 2.5rem 0;
  border: 0;
  height: 1px;
  background: var(--docs-rule-soft);
}

.docs-table-wrap {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  margin: 1.4rem 0;
  min-width: 0;
  max-width: 100%;
}

.docs-content table,
.docs-content .aup-markdown-table {
  width: 100%;
  max-width: 100%;
  margin: 0;
  border-collapse: collapse;
  font-family: var(--font-body, "Inter", system-ui, sans-serif);
  font-size: 0.95rem;
  /* Prefer reflow over max-content expansion (arcblock-site#361). */
  min-width: 0;
  table-layout: auto;
}

.docs-content table th,
.docs-content table td,
.docs-content .aup-markdown-table th,
.docs-content .aup-markdown-table td {
  padding: 0.65rem 0.85rem;
  border-bottom: 1px solid var(--docs-rule-soft);
  text-align: left;
  vertical-align: top;
  overflow-wrap: anywhere;
  word-break: break-word;
}

.docs-content table code,
.docs-content .aup-markdown-table code {
  white-space: normal;
  overflow-wrap: anywhere;
  word-break: break-word;
}

.docs-content table th {
  font-family: var(--font-mono, "JetBrains Mono", ui-monospace, monospace);
  font-size: 0.72rem;
  font-weight: 500;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--color-dim, #6b7280);
  border-bottom: 1px solid var(--docs-rule);
}

/* ── Docs Link/Action Cards (arc#2454 Phase 2) ─────── */
/* Docs-scoped compact card style for `::link-card{...}` / `:::action-card{...}:::`
   (content-reader.ts's `contentCardToAup`, arc#2454 Phase 1), rendered as
   `.aup-view[data-mode="card"][data-variant="docs-link-card"|"docs-action-card"]`.
   Every selector here is scoped under `.docs-content` so it can never leak
   into non-docs surfaces that also load AUP_PRIMITIVES_CSS. Deliberately its
   OWN visual language, not the homepage/collection `.content-card` marketing
   grid above — different field model (single title+description+href vs. a
   collection array), different container (inline in prose vs. a page-width
   section) — see the issue's own "don't reuse the marketing card" constraint.
   Base look (bg/border/radius/shadow) plus hover-lift/focus-visible ring
   already come for free from the shared `.aup-view[data-mode="card"]` /
   `.aup-action` rules in packages/aup/src/primitives-css.ts — everything
   below only adds what's genuinely Docs-specific: grouping/columns, type
   scale for the title/description text roles, the link-card corner
   affordance, and the disabled/unavailable degrade look. */

/* card-group: an `auto-fit`/`minmax()` grid — same technique the
   `content-card` component's own `.content-cards` grid uses (style.css
   above) — so the column count tracks the REAL available width of the docs
   prose column (which itself narrows when the TOC rail is docked), not a
   fixed viewport breakpoint. At the 390px viewport width called out in the
   issue the content column is far below the 2-column threshold and this
   collapses to a single column automatically; on desktop widths the column
   is wide enough for 2 (occasionally 3) cards per row. */
.docs-content .aup-view[data-mode="card-group"] {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 16rem), 1fr));
  gap: 1rem;
  margin: 1.4rem 0;
}

/* A lone (non-grouped) card sitting directly in prose keeps its own block
   vertical rhythm, matching the blockquote/code-block margin above. Cards
   inside a group get that spacing from the grid's own `gap` instead. */
.docs-content .aup-view[data-mode="card"][data-variant^="docs-"] {
  margin: 1.4rem 0;
  min-width: 0; /* grid/flex item: allow shrinking below the intrinsic content
                   minimum so an unbroken long label/URL cannot force this
                   card — or the page — into horizontal scroll. */
}

.docs-content .aup-view[data-mode="card-group"] > .aup-view[data-mode="card"] {
  margin: 0;
}

.docs-content
  .aup-view[data-mode="card"][data-variant^="docs-"]
  .aup-text[data-variant="docs-card-title"] {
  margin: 0 0 0.3rem;
  color: var(--color-text, #0f172a);
  font-family: var(--font-display, "Sora", system-ui, sans-serif);
  font-size: 1rem;
  font-weight: 560;
  line-height: 1.32;
  /* CJK/long-English/URL-as-title robustness: reflow instead of overflowing
     or relying solely on the card's own `overflow: hidden` to silently clip. */
  overflow-wrap: anywhere;
}

.docs-content
  .aup-view[data-mode="card"][data-variant^="docs-"]
  .aup-text[data-variant="docs-card-description"] {
  margin: 0;
  color: var(--docs-muted);
  font-size: 0.86rem;
  line-height: 1.55;
  overflow-wrap: anywhere;
}

/* Missing optional field (no description, or — in the empty-card edge case —
   no title either): nothing here assumes a fixed child count/order, so the
   card simply shows whichever text nodes `contentCardToAup` produced with no
   gap artifacts. No CSS below depends on a specific number of children. */

/* ── link-card: whole card is the <a> (aup-view-link, Phase 0) ─────── */
.docs-content .aup-view[data-mode="card"][data-variant="docs-link-card"] {
  display: flex;
  flex-direction: column;
  gap: 0.2rem;
  padding-right: 2.1rem; /* reserve room for the corner arrow so it never
                             sits under the last line of a full-width
                             description */
  padding-bottom: 2rem;
}

/* Corner "go to" affordance — a plain arrow for in-app navigation, a
   distinct "open in new" glyph when the author set `target="_blank"`
   (perceivable external-link indicator, issue AC), keyed off the real
   `target` attribute `view.ts` already renders (Phase 0) rather than a new
   host-comparison mechanism. Text glyphs, not a new SVG/icon pipeline for a
   purely decorative affordance the underlying `target`/`rel` already backs
   functionally. */
.docs-content .aup-view[data-mode="card"][data-variant="docs-link-card"]::after {
  content: "→";
  position: absolute;
  right: 1.1rem;
  bottom: 1rem;
  color: var(--color-accent, #2563eb);
  font-size: 1.05rem;
  line-height: 1;
  opacity: 0.55;
  transition:
    transform 0.18s ease,
    opacity 0.18s ease;
}

.docs-content .aup-view[data-mode="card"][data-variant="docs-link-card"][target="_blank"]::after {
  content: "↗";
}

.docs-content .aup-view[data-mode="card"][data-variant="docs-link-card"]:hover::after,
.docs-content .aup-view[data-mode="card"][data-variant="docs-link-card"]:focus-visible::after {
  transform: translateX(2px);
  opacity: 0.9;
}

/* :active press feedback — the shared `.aup-view[data-mode="card"]:hover`
   lift (primitives-css.ts) has no matching `:active` reset, so a click
   without this would keep floating at -2px through the press. */
.docs-content .aup-view[data-mode="card"][data-variant="docs-link-card"]:active {
  transform: translateY(0);
  box-shadow: var(--shadow-card);
}

.docs-content .aup-view[data-mode="card"][data-variant="docs-link-card"]:focus-visible {
  outline: 2px solid var(--color-accent, #2563eb);
  outline-offset: 2px;
}

/* Disabled/unavailable (issue AC): no safe href → Phase 0's view.ts already
   degrades this to a plain, non-interactive `<div>` (no `aup-view-link`
   class). Keyed off that existing class difference, not a new prop — makes
   the degrade state read as "not clickable" instead of looking identical to
   a working card minus the click. */
.docs-content .aup-view[data-mode="card"][data-variant="docs-link-card"]:not(.aup-view-link) {
  cursor: default;
  opacity: 0.7;
}

.docs-content
  .aup-view[data-mode="card"][data-variant="docs-link-card"]:not(.aup-view-link)::after {
  content: none;
}

/* ── action-card: title/description block, then a wrapping action row ── */
.docs-content .aup-view[data-mode="card"][data-variant="docs-action-card"] {
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
  align-items: flex-start;
  gap: 0.5rem 0.6rem;
}

/* Not itself a link (Phase 1: action-card never sets `props.href`) — cancel
   the shared card's whole-box hover-lift so only the genuinely-interactive
   nested `.aup-action` buttons look clickable. */
.docs-content .aup-view[data-mode="card"][data-variant="docs-action-card"]:hover {
  transform: none;
}

.docs-content .aup-view[data-mode="card"][data-variant="docs-action-card"] .aup-text {
  flex: 1 1 100%;
}

.docs-content .aup-view[data-mode="card"][data-variant="docs-action-card"] .aup-action {
  flex: 0 1 auto;
  max-width: 100%;
  /* Base `.aup-action` is `white-space: nowrap` (primitives-css.ts) — fine
     for short labels, but an unusually long one must wrap within its own
     button rather than bleeding past the card's edge. */
  white-space: normal;
  text-align: center;
}

/* Disabled/unavailable (issue AC): an action-card authored with no
   `::action{}` children at all (Phase 1's own "empty card, no crash" case) —
   read as an inert info block, same visual treatment as link-card's
   no-href degrade above. */
.docs-content .aup-view[data-mode="card"][data-variant="docs-action-card"]:not(:has(.aup-action)) {
  opacity: 0.7;
}

/* ── info-card: non-interactive Info/Rich Card content block (arc#2546) ──
   `::info-card{title="..." description="..."} ...block content... :::`
   (content-reader.ts's `contentCardToAup`, reused with `withHref: false`)
   is deliberately never a link and never wraps `::action{}` buttons — a
   *genuine* information block, not a degraded/disabled card. It must NOT
   read like the disabled/unavailable states above (link-card's
   `:not(.aup-view-link)` / action-card's `:not(:has(.aup-action))`, both
   `opacity: 0.7`, cursor: default) — that would defeat the whole point of
   this issue (a reader must be able to tell "intentionally informational"
   apart from "broken link" at a glance). Full opacity plus a permanent left
   accent bar is the distinguishing affordance instead. */
.docs-content .aup-view[data-mode="card"][data-variant="docs-info-card"] {
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
  border-left: 3px solid var(--color-accent, #2563eb);
  opacity: 1;
}

/* Never interactive — cancel the shared card's hover-lift AND its
   accent-stripe-on-hover (that stripe means "this responds to hover", which
   an info-card never does — it already has its own permanent left accent
   bar as its identity marker). Same hover-lift cancellation technique
   action-card uses above. */
.docs-content .aup-view[data-mode="card"][data-variant="docs-info-card"]:hover {
  transform: none;
}
.docs-content .aup-view[data-mode="card"][data-variant="docs-info-card"]::before {
  display: none;
}

/* Block-children spacing reset: nested paragraph/list/code-block/callout
   render through the exact same shared/docs prose CSS already used
   elsewhere in the article body (no new mechanism) — only the OUTER spacing
   between them needs a card-scoped reset here, so they don't carry the
   docs-prose margins meant for full-width paragraphs (would look wrong
   inside a padded card). Lower specificity (4 vs 6 class-level selectors)
   than the title/description rules above, so those keep their own margins;
   this only touches generic children (paragraph/list/code/callout) that have
   no more-specific rule of their own. */
.docs-content .aup-view[data-mode="card"][data-variant="docs-info-card"] > * {
  margin: 0;
}
.docs-content .aup-view[data-mode="card"][data-variant="docs-info-card"] > * + * {
  margin-top: 0.5rem;
}

/* ── Card icon (arc#2547) ───────────────────────────── */
/* Controlled, OPTIONAL icon reusing the existing shared icon registry
   (`buildIconSvg`/`ICON_PATHS`, packages/aup/src/icons.ts) — the SAME
   vocabulary the app-footer social icons already consume, not a second icon
   system. `view.ts` resolves `props.icon` (an author-supplied string key) to
   an inline `<svg>` and wraps it in `.aup-card-icon`; unknown/missing keys
   resolve to `null` there and no `.aup-card-icon` span is emitted at all —
   nothing below can create a layout gap for the no-icon/unknown-icon case,
   the element simply isn't in the DOM. Rendered before the title/description
   text nodes; both card variants are `display: flex` containers, so a bare,
   unstretched flex item naturally sits on its own line above the
   `flex: 1 1 100%` title/description block — no extra positioning rules
   needed for link-card (column) vs action-card (row) to agree visually.
   Always decorative (`aria-hidden="true"`, set unconditionally by
   `buildIconSvg` itself) — a Card's title text is required and always
   visible, so the icon is never the sole information carrier. */
.docs-content .aup-view[data-mode="card"][data-variant^="docs-"] .aup-card-icon {
  display: inline-flex;
  color: var(--color-accent, #2563eb);
  margin-bottom: 0.35rem;
}

.docs-content .aup-view[data-mode="card"][data-variant^="docs-"] .aup-card-icon-svg {
  width: 1.25rem;
  height: 1.25rem;
}

/* ── Collection landing entries (arc#2384) ─────────── */
/* Renders the same grouped doc entries as the sidebar nav, in the article
   body, for collection landing pages that have no content.md of their own. */

.docs-entry-groups {
  display: flex;
  flex-direction: column;
  gap: 2.4rem;
}

.docs-entry-group-label {
  margin: 0 0 0.9rem;
  padding: 0;
  border: 0;
  color: var(--color-text, #0f172a);
  font-family: var(--font-display, "Sora", system-ui, sans-serif);
  font-size: 1.1rem;
  font-weight: 500;
  letter-spacing: -0.005em;
}

.docs-entry-list {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: 0.6rem;
  margin: 0;
  padding: 0;
  list-style: none;
}

.docs-entry-item {
  margin: 0;
}

.docs-entry-link {
  display: block;
  padding: 0.85rem 1rem;
  border: 1px solid var(--docs-rule-soft);
  border-radius: 10px;
  color: var(--color-text, #0f172a);
  font-family: var(--font-body, "Inter", system-ui, sans-serif);
  font-size: 0.94rem;
  font-weight: 460;
  text-decoration: none;
  transition:
    border-color 0.18s ease,
    background 0.18s ease;
}

.docs-entry-link:hover {
  border-color: color-mix(in srgb, var(--color-accent, #2563eb) 40%, var(--docs-rule));
  background: color-mix(in srgb, var(--color-accent, #2563eb) 4%, transparent);
}

.docs-content-empty {
  padding: 2rem;
  border: 1px dashed var(--docs-rule);
  border-radius: 12px;
  color: var(--docs-muted);
  font-family: var(--font-body, "Inter", system-ui, sans-serif);
}

/* ── Collection homepage: recursive `_nav.yaml` listing (arc#2436 Phase 4) ── */
/* Tree-mode equivalent of .docs-entry-groups above — same collection-homepage
   body slot, computed from the same navTree the sidebar renders. */

.docs-entry-tree-root,
.docs-entry-tree-children {
  margin: 0;
  padding: 0;
  list-style: none;
}

.docs-entry-tree-root {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

.docs-entry-tree-children {
  padding-left: 1.4rem;
  margin-top: 0.5rem;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

.docs-entry-tree-label {
  display: block;
  padding: 0.3rem 0;
  color: var(--color-text, #0f172a);
  font-family: var(--font-display, "Sora", system-ui, sans-serif);
  font-size: 1rem;
  font-weight: 500;
}

.docs-entry-tree .docs-entry-link {
  display: inline-block;
}

/* ── Pager ────────────────────────────────────────── */

.docs-pager {
  margin: 3.5rem 0 0;
  padding-top: 1.8rem;
  border-top: 1px solid var(--docs-rule);
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: 1rem;
}

.docs-pager-link {
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
  padding: 1rem 1.2rem;
  border: 1px solid var(--docs-rule-soft);
  border-radius: 10px;
  color: var(--color-text, #0f172a);
  font-family: var(--font-body, "Inter", system-ui, sans-serif);
  text-decoration: none;
  transition:
    border-color 0.18s ease,
    transform 0.18s ease,
    background 0.18s ease;
}

.docs-pager-link:hover {
  border-color: color-mix(in srgb, var(--color-accent, #2563eb) 40%, var(--docs-rule));
  background: color-mix(in srgb, var(--color-accent, #2563eb) 4%, transparent);
}

.docs-pager-link.is-next {
  text-align: right;
  align-items: flex-end;
}

.docs-pager-direction {
  color: var(--color-dim, #6b7280);
  font-family: var(--font-mono, "JetBrains Mono", ui-monospace, monospace);
  font-size: 0.7rem;
  font-weight: 500;
  letter-spacing: 0.16em;
  text-transform: uppercase;
}

.docs-pager-label {
  font-family: var(--font-display, "Sora", system-ui, sans-serif);
  font-size: 1rem;
  font-weight: 460;
  letter-spacing: -0.005em;
}

/* Keep detail navigation on the same measure as the article and lower
   its visual weight so it closes the reading flow instead of resembling two
   prominent call-to-action cards. */
.docs-pager {
  max-width: var(--docs-content);
  margin-top: 3rem;
  padding-top: 0;
  border-top: 0;
  gap: 0.75rem;
}

.docs-pager-link {
  min-width: 0;
  flex-direction: row;
  align-items: center;
  padding: 1rem 1.1rem;
  border-color: transparent;
  border-radius: 6px;
  background: var(--docs-soft-bg);
}

.docs-pager-link.is-next {
  align-items: center;
  justify-content: flex-end;
}

.docs-pager-link.is-prev .docs-pager-direction {
  margin-right: 0.65rem;
}

.docs-pager-link.is-next .docs-pager-direction {
  order: 2;
  margin-left: 0.65rem;
}

.docs-pager-label {
  min-width: 0;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}

/* ── Responsive ───────────────────────────────────── */

@media (max-width: 960px) {
  .docs-shell {
    grid-template-columns: 1fr;
    gap: 1.25rem;
  }

  .docs-heading {
    flex-wrap: wrap;
  }

  .docs-heading-actions {
    order: -1;
    justify-content: flex-end;
    width: 100%;
  }

  .docs-sidebar {
    position: static;
    max-height: none;
    padding: 0.85rem 1.1rem;
    border: 1px solid var(--docs-rule-soft);
    border-radius: 12px;
    background: color-mix(in srgb, var(--color-surface, #fafafa) 92%, transparent);
  }

  .docs-sidebar-brand {
    margin-bottom: 0.85rem;
  }

  /* Collapsed by default — only the toggle (showing the current section) is
     visible until the user opens the drawer (arc#2303). */
  .docs-nav-toggle {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.6rem;
    width: 100%;
    padding: 0.6rem 0.85rem;
    border: 1px solid var(--docs-rule);
    border-radius: 9px;
    background: var(--color-surface, #fafafa);
    color: var(--color-text, #0f172a);
    font-family: var(--font-body, "Inter", system-ui, sans-serif);
    font-size: 0.92rem;
    font-weight: 500;
    cursor: pointer;
  }

  .docs-nav-toggle-label {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  .docs-nav-toggle-icon {
    width: 0.55rem;
    height: 0.55rem;
    flex-shrink: 0;
    border-right: 2px solid currentColor;
    border-bottom: 2px solid currentColor;
    transform: rotate(45deg);
    transition: transform 0.18s ease;
  }

  .docs-nav-toggle[aria-expanded="true"] .docs-nav-toggle-icon {
    transform: rotate(-135deg);
  }

  .docs-sidebar-nav {
    display: none;
    grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
    gap: 1rem;
    margin-top: 0.85rem;
  }

  /* .docs-nav-backdrop is `position: fixed; z-index: 20`; without an
     explicit stacking context the open sidebar (position: static above)
     painted below it, leaving nav links unclickable while the drawer was
     open (arc#2303 follow-up). */
  .docs-sidebar.is-open {
    position: relative;
    z-index: 21;
  }

  .docs-sidebar.is-open .docs-sidebar-nav {
    display: grid;
  }

  .docs-sidebar {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    padding: 0.65rem 0.85rem;
  }

  .docs-sidebar-brand {
    flex: 1;
    min-width: 0;
    margin: 0;
  }

  .docs-nav-toggle {
    width: auto;
    max-width: 55%;
    flex: 0 1 auto;
  }

  /* arc#2450: the toggle now renders in `.docs-entry-bar` (beside the
     breadcrumb) instead of inside `.docs-sidebar`, and
     the site-name brand row is redundant with the global Header — hide both
     in the closed state. Without the second rule, the base ≤960px
     `.docs-sidebar` rule above still gives this element a border/background/
     border-radius/padding even though every child is now hidden or moved
     out — a visible empty box sitting above the entry-bar. `.is-open`
     restores full-drawer display via the existing rule below (mutually
     exclusive by `:not()`, not by source order). */
  .docs-sidebar-brand {
    display: none;
  }

  .docs-sidebar:not(.is-open) {
    display: none;
  }

  .docs-sidebar.is-open {
    position: fixed;
    inset: 0 auto 0 0;
    z-index: 1002;
    display: block;
    width: min(88vw, 360px);
    height: 100dvh;
    max-height: none;
    box-sizing: border-box;
    padding: 1rem;
    overflow-y: auto;
    border-radius: 0 14px 14px 0;
    background: var(--color-bg, #fff);
  }

  .docs-sidebar.is-open .docs-sidebar-brand {
    display: inline-flex;
    margin: 0 2.75rem 1rem 0;
  }

  .docs-sidebar.is-open .docs-nav-toggle {
    width: 100%;
    max-width: none;
  }

  .docs-nav-close {
    position: absolute;
    top: 0.85rem;
    right: 0.85rem;
    display: none;
    width: 2.25rem;
    height: 2.25rem;
    border: 1px solid var(--docs-rule);
    border-radius: 8px;
    background: var(--color-surface, #fafafa);
    color: var(--color-text, #0f172a);
    cursor: pointer;
  }

  .docs-sidebar.is-open .docs-nav-close {
    display: block;
  }

  .docs-nav-close span::before,
  .docs-nav-close span::after {
    content: "";
    position: absolute;
    top: 50%;
    left: 50%;
    width: 1rem;
    height: 2px;
    background: currentColor;
  }

  .docs-nav-close span::before {
    transform: translate(-50%, -50%) rotate(45deg);
  }

  .docs-nav-close span::after {
    transform: translate(-50%, -50%) rotate(-45deg);
  }

  .docs-nav-backdrop:not([hidden]) {
    z-index: 1001;
  }

  .docs-nav-backdrop:not([hidden]) {
    display: block;
  }

  /* arc#2450: breadcrumb collapses from 3 segments ("Docs / Collection /
     Current") to 2 ("Collection › Current page") on mobile. Hides by DOM
     position rather than reworking `breadcrumbHtml`'s generation, so the
     desktop breadcrumb output — and its 3-segment a11y tree — is untouched;
     only visibility changes below this breakpoint. A page with no collection
     (2-segment breadcrumb: Docs / Current) collapses to just "Current",
     which is the correct behavior — there is no intermediate level to keep. */
  .docs-breadcrumb > :nth-child(1),
  .docs-breadcrumb > :nth-child(2) {
    display: none;
  }

  /* arc#2450 adversarial-pass fix: a pathologically long collection label or
     page title (real-world case: a long CJK collection name) otherwise wraps
     the breadcrumb across several lines, defeating the whole point of a
     "compact" entry row and pushing the toggle button awkwardly off-center.
     `min-width: 0` lets the flex row/items shrink below their content size
     (the flexbox default `min-width: auto` is exactly what blocks
     shrinking); each remaining visible segment then truncates independently
     instead of wrapping. The `:not([aria-hidden])` guard leaves the tiny "/"
     separator alone — it's already short and shouldn't need an ellipsis. */
  .docs-entry-bar .docs-breadcrumb {
    flex: 1 1 0;
    min-width: 0;
    flex-wrap: nowrap;
  }

  .docs-entry-bar .docs-breadcrumb > a,
  .docs-entry-bar .docs-breadcrumb > span:not([aria-hidden]) {
    overflow: hidden;
    min-width: 0;
    white-space: nowrap;
    text-overflow: ellipsis;
  }

  /* arc#2450: the heavy divider directly under the H1 is one of the stacked
     elements pushing the first paragraph down; dropping it (mobile only,
     desktop keeps the base rule) is pure spacing, no content is hidden. */
  .docs-heading {
    padding-bottom: 0;
    border-bottom: 0;
    margin-bottom: 1rem;
  }

  .docs-toc {
    order: -1;
    position: static;
    max-height: none;
    padding: 0.85rem 1.1rem;
    border: 1px solid var(--docs-rule-soft);
    border-radius: 12px;
    background: color-mix(in srgb, var(--color-surface, #fafafa) 92%, transparent);
  }

  .docs-toc-list {
    border-left: 0;
  }

  .docs-toc-link {
    padding-left: 0.5rem;
  }

  .docs-toc-item--h3 .docs-toc-link {
    padding-left: 1.3rem;
  }

  /* arc#2450: overrides the blanket .docs-toc order:-1 rule above (higher
     specificity wins regardless of source order) so the TOC disclosure no
     longer blocks the article body — the DOM already places .docs-content
     before .docs-toc (render.js), this simply stops CSS from visually
     reversing that order. */
  .docs-toc {
    order: 0;
    padding: 0;
    overflow: visible;
    background: transparent;
    /* arc#2935 item 7 (deliberately NOT spelling out the widget's own
       hyphenated class-name-shaped identifier here — this stylesheet is
       always embedded, comments enabled or not, and a detail-mount test
       elsewhere in this package asserts that exact string is absent from a
       no-comments page's rendered HTML): this rule strips the
       desktop/tablet .docs-toc box's own padding+background (arc#2450,
       above), but .docs-body's last child on this breakpoint, when the
       comments widget is mounted, is ITS OWN card content — that sibling
       stylesheet only gives IT a margin-top, nothing pushes the TOC away
       from whatever precedes it. The "On this page" toggle bar landed flush
       against the comment card below it: same width, same-ish background,
       zero gap, reading as one merged block. --space-section is the same
       canonical "separate this section from whatever precedes it" token
       that sibling stylesheet's own margin-top already uses (its line 16)
       — .docs-pager (line ~1327) reaches the same outcome with a hardcoded
       3.5rem instead; --space-section is used here so the gap scales with
       the active density/theme preset like the rest of this shared-token
       widget does, not a third
       independent magic number. */
    margin-top: var(--space-section);
  }
}

@media (max-width: 720px) {
  .docs-shell {
    width: min(100% - 36px, 1280px);
    padding-top: 1.5rem;
  }

  .docs-pager {
    grid-template-columns: 1fr;
  }

  .docs-pager-link.is-next {
    text-align: left;
    align-items: flex-start;
  }
}

/* CJK rhythm: zero out negative tracking, give breathing room on body lines. */
:where([lang|="zh"], [lang="ja"], [lang="ko"]) .docs-title,
:where([lang|="zh"], [lang="ja"], [lang="ko"]) .docs-content h2,
:where([lang|="zh"], [lang="ja"], [lang="ko"]) .docs-content h3,
:where([lang|="zh"], [lang="ja"], [lang="ko"]) .docs-content h4,
:where([lang|="zh"], [lang="ja"], [lang="ko"]) .docs-entry-group-label,
:where([lang|="zh"], [lang="ja"], [lang="ko"]) .docs-pager-label {
  letter-spacing: 0;
  font-feature-settings: "palt" 1;
}

:where([lang|="zh"], [lang="ja"], [lang="ko"]) .docs-content,
:where([lang|="zh"], [lang="ja"], [lang="ko"]) .docs-summary {
  line-height: 1.86;
  font-feature-settings: "palt" 1;
}

/* A compact reading header; native sidebar, TOC, copy actions and body are untouched. */
.docs-heading{padding:24px 26px 26px;border-top:3px solid var(--color-accent);border-bottom:1px solid var(--docs-rule);background:linear-gradient(110deg,color-mix(in srgb,var(--color-accent) 7%,var(--color-bg)),var(--color-bg));border-radius:0 0 8px 8px}.docs-heading .docs-title{font-size:clamp(30px,3.1vw,43px);line-height:1.2;letter-spacing:-.03em;text-wrap:balance}.docs-heading .docs-summary{font-size:16px;line-height:1.8;max-width:48em}.docs-heading .docs-eyebrow{margin-bottom:16px}
@media(max-width:760px){.docs-heading{padding:20px 18px}.docs-heading .docs-title{font-size:30px}.docs-heading .docs-summary{font-size:15px}}
