@font-face{font-family:'Nunito';font-style:normal;font-weight:200 1000;font-display:swap;src:url("/fonts/nunito-latin-normal.woff2") format('woff2');unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;}
@font-face{font-family:'Nunito';font-style:normal;font-weight:200 1000;font-display:swap;src:url("/fonts/nunito-latin-ext-normal.woff2") format('woff2');unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF;}
@font-face{font-family:'Nunito';font-style:italic;font-weight:200 1000;font-display:swap;src:url("/fonts/nunito-latin-italic.woff2") format('woff2');unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;}
@font-face{font-family:'Nunito';font-style:italic;font-weight:200 1000;font-display:swap;src:url("/fonts/nunito-latin-ext-italic.woff2") format('woff2');unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF;}
:root{color-scheme:light;--stu-primary:#8b6914;--stu-on-primary:#FFFFFF;--stu-background:#fefdf7;--stu-surface:#FFFFFF;--stu-border:#ABB1B5;--stu-ink:#1A1A1A;--stu-muted:#5c564e;--stu-link:#8b6914;--stu-radius:8px;--stu-shadow:0 1px 8px rgba(0, 0, 0, 0.12);}
:root[data-theme="dark"]{color-scheme:dark;--stu-on-primary:#FFFFFF;--stu-background:#141311;--stu-surface:#1A1715;--stu-border:#444444;--stu-ink:#eeeae2;--stu-muted:#B0A898;--stu-shadow:none;--stu-primary:#b58e2d;--stu-link:#b58e2d;}
*, *::before, *::after { box-sizing: border-box; }
/* Always reserve the scrollbar gutter so the viewport width is constant. Without this a
   short page (no scrollbar) is ~15px wider than a tall one, and the right-aligned nav
   jumps sideways between pages. */
html { scrollbar-gutter: stable; }
/* One knob for the site content width: sections, header and footer all align to it. */
:root { --stu-wide: 90rem; --stu-contained: 72rem; --stu-header-h: 4rem; }
body { margin: 0; background: var(--stu-background, #ffffff); color: var(--stu-ink, #1f2430);
    font-family: 'Nunito', system-ui, -apple-system, sans-serif;
    /* Sticky footer: fill the viewport so the footer sits at the bottom on short
       pages, and only comes into view after scrolling on tall ones. */
    display: flex; flex-direction: column; min-height: 100vh; }
.stu-page { max-width: var(--stu-wide, 90rem); margin: 0 auto; padding: 1.5rem;
    color: var(--stu-ink, #1f2430); line-height: 1.5; }
/* Section pages run full width; each section's inner wrapper sets the content width. */
.stu-page--full { max-width: none; padding: 0; }
.stu-section__inner { width: 100%; margin-inline: auto; padding-inline: 1.5rem;
    padding-block: 1.5rem; }
.stu-w-contained { max-width: var(--stu-contained, 72rem); }
.stu-w-wide { max-width: var(--stu-wide, 90rem); }
.stu-w-full { max-width: none; }
.stu-row { display: flex; flex-wrap: wrap; gap: 1rem; }
.stu-col { flex-grow: 1; flex-shrink: 1; flex-basis: 0; min-width: 0; }
.stu-col-1 { flex-grow: 1; } .stu-col-2 { flex-grow: 2; } .stu-col-3 { flex-grow: 3; }
.stu-col-4 { flex-grow: 4; } .stu-col-5 { flex-grow: 5; } .stu-col-6 { flex-grow: 6; }
.stu-col-7 { flex-grow: 7; } .stu-col-8 { flex-grow: 8; } .stu-col-9 { flex-grow: 9; }
.stu-col-10 { flex-grow: 10; } .stu-col-11 { flex-grow: 11; } .stu-col-12 { flex-grow: 12; }

.stu-section { display: block; }
.stu-el { margin: 0; }
.stu-align-center { text-align: center; }
.stu-align-right { text-align: right; }
/* Block-level media ignores text-align, so nudge it with auto margins. */
.stu-align-center img, .stu-align-center .stu-video { margin-left: auto; margin-right: auto; }
.stu-align-right img, .stu-align-right .stu-video { margin-left: auto; margin-right: 0; }
/* A button row is a flex row, so align positions it with justify-content, not text-align. */
.stu-align-center .stu-btn-row { justify-content: center; }
.stu-align-right .stu-btn-row { justify-content: flex-end; }

.stu-text { margin: 0; white-space: pre-wrap; }
.stu-text-bold { font-weight: 700; }
.stu-text-italic { font-style: italic; }
.stu-text-primary { color: var(--stu-link, #2563eb); }
.stu-text-muted { color: var(--stu-muted, #6b7280); }
.stu-text-sm { font-size: 0.875rem; }
.stu-text-lg { font-size: 1.25rem; }
.stu-text-xl { font-size: 1.5rem; }
.stu-image { display: block; max-width: 100%; height: auto; border-radius: var(--stu-radius, 8px); }
.stu-button { display: inline-block; padding: 0.625rem 1.25rem;
    background: var(--stu-primary, #2563eb); color: var(--stu-on-primary, #ffffff);
    border-radius: var(--stu-radius, 8px); box-shadow: var(--stu-shadow, none);
    text-decoration: none; border: 0; font: inherit; cursor: pointer;
    transition: background 0.12s ease, transform 0.12s ease; }
/* Hover darkens the fill in light mode and lightens it in dark, so the shade tracks the
   brand color. Excludes the badge, which has no fill to tint. */
.stu-button:hover:not(.stu-button--badge) { background: color-mix(in srgb, var(--stu-primary, #2563eb) 84%, #000); }
:root[data-theme="dark"] .stu-button:hover:not(.stu-button--badge) { background: color-mix(in srgb, var(--stu-primary, #2563eb) 85%, #fff); }
.stu-button:active { transform: translateY(1px); }
.stu-button:focus-visible { outline: 2px solid var(--stu-link, #2563eb); outline-offset: 2px; }
/* App-store badge: strip the button chrome so only the official artwork shows,
   sized to the same height as a text button, width from the artwork's ratio. */
.stu-button--badge { padding: 0; background: none; box-shadow: none;
    border-radius: 0; line-height: 0; transition: opacity 0.12s ease; }
.stu-button--badge:hover { opacity: 0.88; }
.stu-badge { display: block; height: 2.75rem; width: auto; }
.stu-btn-row { display: flex; flex-wrap: wrap; align-items: center; gap: 0.75rem; }
.stu-link { color: var(--stu-link, #2563eb); }
.stu-form { display: flex; gap: 0.5rem; flex-wrap: wrap; }
.stu-form__input { padding: 0.625rem 0.75rem; border: 1px solid #ccc;
    border-radius: var(--stu-radius, 8px); flex: 1 1 12.5rem; }
.stu-form__hp { position: absolute; left: -9999px; width: 1px; height: 1px; opacity: 0; }
.stu-form__msg { flex-basis: 100%; margin-top: 0.25rem; font-size: 0.9rem; opacity: 0.85; }

/* Blog index: filter toolbar + responsive card grid. Spacing in rem, 4px (0.25rem) steps. */
.stu-blog-toolbar { display: flex; justify-content: space-between; align-items: center;
    gap: 0.75rem; flex-wrap: wrap; margin: 1rem 0 1.5rem; }
.stu-blog-filters { display: flex; gap: 0.5rem; flex-wrap: wrap; }
.stu-blog-select, .stu-blog-search { padding: 0.5rem 0.75rem; border: 1px solid rgba(128,128,128,0.35);
    border-radius: var(--stu-radius, 8px); font: inherit; background: var(--stu-surface, #fff); color: inherit; }
.stu-blog-select { -webkit-appearance: none; -moz-appearance: none; appearance: none;
    padding-right: 2rem; background-repeat: no-repeat; background-position: right 0.75rem center;
    background-size: 0.625rem;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 10 6'%3E%3Cpath fill='none' stroke='%23555' stroke-width='1.5' d='M1 1l4 4 4-4'/%3E%3C/svg%3E"); }
.stu-blog-search { min-width: 12.5rem; }
.stu-blog-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 3rem; }
.stu-blog-card { display: flex; flex-direction: column; border-radius: var(--stu-radius, 8px);
    overflow: hidden; border: 1px solid rgba(128,128,128,0.2);
    background: var(--stu-surface, #fff); transition: transform 0.1s ease, border-color 0.1s ease; }
.stu-blog-card:hover { transform: translateY(-2px); border-color: var(--stu-primary, #2563eb); }
/* The link grows to fill the card, so the meta row sits at the bottom of every card in a grid row. */
.stu-blog-card__link { flex: 1; display: flex; flex-direction: column; text-decoration: none; color: inherit; }
.stu-blog-card__img { display: block; aspect-ratio: 16 / 9; background-size: cover;
    background-position: center; background-color: #e9e5dc; }
.stu-blog-card__body { padding: 0.75rem 1rem 0.5rem; display: flex; flex-direction: column; gap: 0.5rem; }
.stu-blog-card__title { font-weight: 700; font-size: 1.05rem; line-height: 1.25; }
.stu-blog-card__excerpt { font-size: 0.9rem; opacity: 0.8;
    display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden; }
.stu-blog-card__meta { display: flex; justify-content: space-between; align-items: center;
    padding: 0 1rem 0.75rem; font-size: 0.8rem; opacity: 0.7; }
.stu-blog-card__tag { color: var(--stu-link, #c0392b); font-weight: 600; font: inherit;
    font-size: 0.8rem; background: none; border: 0; padding: 0; margin: 0; cursor: pointer; }
.stu-blog-card__tag:hover { text-decoration: underline; }
.stu-blog-empty { opacity: 0.7; }
/* Consistent accent focus ring on the blog controls, replacing the browser default. The
   card link uses an inset offset so the card's overflow:hidden does not clip it. */
.stu-blog-select:focus-visible, .stu-blog-search:focus-visible,
.stu-blog-card__tag:focus-visible { outline: 2px solid var(--stu-link, #2563eb); outline-offset: 2px; }
.stu-blog-card__link:focus-visible { outline: 2px solid var(--stu-link, #2563eb); outline-offset: -2px; }
@media (max-width: 900px) { .stu-blog-grid { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 640px) { .stu-blog-grid { grid-template-columns: 1fr; }
    .stu-blog-toolbar { flex-direction: column; align-items: stretch; }
    .stu-blog-search { min-width: 0; } }
.stu-video { position: relative; }
.stu-video iframe { width: 100%; aspect-ratio: 16 / 9; border: 0; }
.stu-video__file { display: block; width: 100%; height: auto; border-radius: var(--stu-radius, 8px); }

/* Media dialog: images and videos open full screen on click (videos with controls through
   the expand button). The script in PageRenderer builds the dialog and the wrappers. */
.stu-zoomable { cursor: zoom-in; }
.stu-lightbox-wrap { position: relative; width: fit-content; max-width: 100%; }
.stu-lightbox-wrap > video { display: block; max-width: 100%; height: auto; }
.stu-lightbox__btn { position: absolute; top: 0.5rem; right: 0.5rem; z-index: 1;
    display: flex; align-items: center; justify-content: center; width: 2.5rem; height: 2.5rem;
    padding: 0; border: 0; border-radius: var(--stu-radius, 8px); cursor: pointer;
    background: rgba(0,0,0,0.55); color: #fff; transition: background 0.12s ease; }
/* The blank-line spacer pads the wrapper, so drop the button past that padding. */
.stu-prose > br + .stu-lightbox-wrap > .stu-lightbox__btn { top: 2rem; }
.stu-lightbox__btn:hover { background: rgba(0,0,0,0.75); }
.stu-lightbox__btn:focus-visible { outline: 2px solid #fff; outline-offset: 2px; }
.stu-lightbox__btn svg { width: 1.25rem; height: 1.25rem; }
.stu-lightbox { position: fixed; inset: 0; width: 100dvw; height: 100dvh; z-index: 100;
    display: flex; align-items: center; justify-content: center;
    padding: 4rem 1rem; background: rgba(0,0,0,0.85); }
.stu-lightbox__box { display: flex; align-items: center; justify-content: center;
    width: 100%; height: 100%; }
.stu-lightbox__media { display: block; max-width: 100%; max-height: 100%; width: auto; height: auto;
    object-fit: contain; border-radius: var(--stu-radius, 8px); }
.stu-lightbox__close { position: fixed; top: 1rem; right: 1rem; }

/* Card element: a bordered box with an optional image over a markdown body. It follows the
   theme: --stu-surface fill, --stu-border edge, --stu-radius corners. Border-defined like the
   admin and SnugTranscribe cards, so no shadow. */
.stu-card { background: var(--stu-surface, #fff); border: 1px solid var(--stu-border, #ABB1B5);
    border-radius: var(--stu-radius, 8px); padding: 1.5rem; }
.stu-card__img { display: block; max-width: 100%; height: auto; margin: 0 auto 1rem; }
/* Body styling is scoped to the card and kept light, so it never pulls in the docs prose look.
   First and last child margins collapse to the card padding. */
.stu-card__body > :first-child { margin-top: 0; }
.stu-card__body > :last-child { margin-bottom: 0; }
.stu-card__body h1, .stu-card__body h2, .stu-card__body h3, .stu-card__body h4 { margin: 0 0 0.5rem; line-height: 1.25; }
.stu-card__body p { margin: 0 0 0.75rem; }
.stu-card__body ul, .stu-card__body ol { margin: 0 0 0.75rem; padding-left: 1.25rem; }
.stu-card__body li { margin: 0.25rem 0; }
.stu-card__body a { color: var(--stu-link, #2563eb); }
.stu-card__body img { max-width: 100%; height: auto; border-radius: var(--stu-radius, 8px); }
/* A card set to fill grows to the column's height, so cards side by side line up at the
   bottom. The row already stretches every column to the tallest one, so the work is
   getting that height down through the stu-el wrapper to the card. A card under a
   heading fills only the leftover space, because the wrapper is the growing flex item.
   Once the columns stack, each sits on its own flex line and is only as tall as its own
   content, so this stops mattering on mobile by itself. */
.stu-col--fill { display: flex; flex-direction: column; }
.stu-col--fill > .stu-el--fill { flex: 1 1 auto; }
.stu-el--fill > .stu-card { height: 100%; }

/* Shared site chrome: header nav + footer. */
.stu-header { position: sticky; top: 0; z-index: 10;
    background: var(--stu-background, #ffffff); border-bottom: 1px solid rgba(128,128,128,0.2);
    color: var(--stu-ink, #1f2430); }
/* Fixed height so the sticky docs sidebar can offset by it and not jump when scrolling. */
.stu-header__inner { position: relative; max-width: var(--stu-wide, 90rem); margin: 0 auto; padding: 0.75rem 1.5rem;
    display: flex; align-items: center; gap: 0.5rem; height: var(--stu-header-h); }
.stu-brand { font-weight: 800; font-size: 1.25rem; color: inherit; text-decoration: none; margin-right: auto; }
.stu-brand__logo { display: block; max-height: 2rem; width: auto; }
.stu-nav { display: flex; align-items: center; gap: 0.25rem; }
.stu-nav__link { color: inherit; text-decoration: none; font-weight: 600; padding: 0.625rem 1.25rem; border-radius: var(--stu-radius, 8px); }
.stu-nav__link:hover { color: var(--stu-link, #2563eb); background: color-mix(in srgb, var(--stu-link, #2563eb) 10%, transparent); }
.stu-nav__link--active { color: var(--stu-link, #2563eb); background: color-mix(in srgb, var(--stu-link, #2563eb) 14%, transparent); }
.stu-nav__cta { margin-left: 0.5rem; }
/* Theme toggle: a bare icon button. The moon shows in light (click to go dark), the sun in dark. */
.stu-theme-toggle { display: inline-flex; align-items: center; justify-content: center;
    background: none; border: 0; color: inherit; cursor: pointer; line-height: 0;
    padding: 0.5rem; border-radius: var(--stu-radius, 8px); }
.stu-theme-toggle:hover { color: var(--stu-link, #2563eb); }
.stu-theme-toggle svg { width: 1.25rem; height: 1.25rem; fill: currentColor; }
.stu-theme-toggle__sun { display: none; }
:root[data-theme="dark"] .stu-theme-toggle__sun { display: block; }
:root[data-theme="dark"] .stu-theme-toggle__moon { display: none; }
.stu-main { display: block; flex: 1 0 auto; }
.stu-footer { border-top: 1px solid rgba(128,128,128,0.2); color: var(--stu-muted, #6b7280); }
.stu-footer__inner { max-width: var(--stu-wide, 90rem); margin: 0 auto; padding: 1.5rem; font-size: 0.875rem;
    display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 0.5rem 1.25rem; }
.stu-footer__links { display: flex; flex-wrap: wrap; align-items: center; gap: 0.75rem 1.25rem; }
.stu-footer__link { color: inherit; text-decoration: none; font: inherit; font-size: 0.875rem;
    background: none; border: 0; padding: 0; cursor: pointer; }
.stu-footer__link:hover { color: var(--stu-link, #2563eb); text-decoration: underline; }

/* Docs mini-site: a sidebar tree on the left, the article on the right. */
.stu-docs { display: flex; align-items: flex-start; max-width: var(--stu-wide, 90rem);
    margin: 0 auto; width: 100%; flex: 1 0 auto; }
/* The column stretches full height so its divider runs the whole page; the inner wrapper
   is the sticky part, so it stays in view as the article scrolls. */
.stu-docs__sidebar { flex: 0 0 16rem; width: 16rem; align-self: stretch;
    border-right: 1px solid rgba(128,128,128,0.2); }
/* Only the tree scrolls, not the whole sidebar, so the search results dropdown is not
   inside an overflow container and can float on top of the nav instead of being clipped. */
.stu-docs__sidebar-inner { position: sticky; top: var(--stu-header-h); max-height: calc(100vh - var(--stu-header-h));
    display: flex; flex-direction: column; padding: 1.5rem 0.5rem; }
.stu-docs__search { position: relative; flex: 0 0 auto; padding: 0 0.25rem 0.75rem; }
.stu-docs__search-box { position: relative; }
.stu-docs__search-input { width: 100%; box-sizing: border-box; padding: 0.5rem 2rem 0.5rem 0.75rem;
    border: 1px solid rgba(128,128,128,0.25); border-radius: var(--stu-radius, 8px);
    font: inherit; font-size: 0.9rem; background: var(--stu-surface, #fff); color: inherit; }
/* Desktop hint: press "/" to search. Hidden on touch and while the box is focused. */
.stu-docs__kbd { position: absolute; right: 0.5rem; top: 50%; transform: translateY(-50%);
    border: 1px solid rgba(128,128,128,0.3); border-radius: 0.25rem; padding: 0 0.35rem;
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 0.8rem; line-height: 1.4;
    color: var(--stu-muted, #6b7280); background: rgba(128,128,128,0.1); pointer-events: none; }
.stu-docs__search-input:focus + .stu-docs__kbd { display: none; }
@media (hover: none) { .stu-docs__kbd { display: none; } }
.stu-docs__results { position: absolute; left: 0.25rem; right: 0.25rem; top: 100%; margin-top: -0.5rem;
    z-index: 20; background: var(--stu-surface, #fff); border: 1px solid rgba(128,128,128,0.25);
    border-radius: var(--stu-radius, 8px); box-shadow: 0 8px 24px rgba(0,0,0,0.12);
    max-height: 24rem; overflow-y: auto; }
.stu-docs__result-msg { padding: 0.75rem 1rem; color: var(--stu-muted, #6b7280); font-size: 0.9rem; }
.stu-docs__result { display: block; padding: 0.5rem 0.75rem; text-decoration: none; color: inherit;
    border-bottom: 1px solid rgba(128,128,128,0.15); }
.stu-docs__result:last-child { border-bottom: 0; }
.stu-docs__result.is-active { background: rgba(128,128,128,0.14); }
.stu-docs__result-title { display: block; font-weight: 700; font-size: 0.9rem;
    color: var(--stu-ink, #1f2430); }
.stu-docs__result-snippet { display: block; font-size: 0.8rem; color: var(--stu-muted, #6b7280);
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.stu-docs__result-snippet mark { background: rgba(255,214,0,0.4); color: inherit;
    padding: 0 0.1em; border-radius: 0.15rem; }
.stu-docs__nav { display: block; flex: 1 1 auto; min-height: 0; overflow-y: auto; }
.stu-docs__tree, .stu-docs__children { list-style: none; margin: 0; padding: 0; }
.stu-docs__children { padding-left: 0.75rem; }
.stu-docs__node[hidden] { display: none; }
/* The whole row is the hover/active surface, so the toggle arrow sits inside the highlight. */
.stu-docs__row { display: flex; align-items: center; border-radius: var(--stu-radius, 8px); }
.stu-docs__row:hover { background: rgba(128,128,128,0.12); }
.stu-docs__row:has(> .stu-docs__link--active) { background: rgba(128,128,128,0.1); }
.stu-docs__toggle { flex: 0 0 auto; width: 1.75rem; height: 1.75rem; border: 0; background: none;
    cursor: pointer; padding: 0; display: flex; align-items: center; justify-content: center; color: inherit; }
.stu-docs__toggle-spacer { flex: 0 0 auto; width: 1.25rem; }
/* A CSS triangle: points down when expanded (default), right when the node is collapsed. */
.stu-docs__toggle::before { content: ''; border-style: solid; border-width: 0.3rem 0 0.3rem 0.45rem;
    border-color: transparent transparent transparent currentColor; transform: rotate(90deg);
    transition: transform 0.15s ease; opacity: 0.55; }
.stu-docs__toggle:hover { color: var(--stu-link, #2563eb); }
.stu-docs__toggle:hover::before { opacity: 1; }
.stu-docs__node.collapsed > .stu-docs__row .stu-docs__toggle::before { transform: rotate(0deg); }
.stu-docs__node.collapsed > .stu-docs__children { display: none; }
.stu-docs__link { display: block; flex: 1 1 auto; min-width: 0; padding: 0.375rem; color: inherit;
    text-decoration: none; font-size: 0.95rem; line-height: 1.3;
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* Toggled rows already have the toggle's width before the label, so drop the link's
   left padding there; leaf rows keep it so their labels line up. */
.stu-docs__toggle + .stu-docs__link { padding-left: 0; }
.stu-docs__link--active { color: var(--stu-link, #2563eb); font-weight: 700; }
.stu-docs__main { flex: 1 1 auto; min-width: 0; }
.stu-docs__article { max-width: 52rem; padding: 1.5rem 2rem; color: var(--stu-ink, #1f2430); }

/* Shared prose typography for every markdown-rendered body: docs, blog posts, and legal
   pages. Each container also carries .stu-prose. Values follow github-markdown-css. Builder
   pages are component-built and do not use this class, so their layout is untouched. */
.stu-prose { max-width: 52rem; line-height: 1.5; }
.stu-prose > :first-child { margin-top: 0; }
.stu-prose > :last-child { margin-bottom: 0; }
.stu-prose p, .stu-prose ul, .stu-prose ol, .stu-prose blockquote,
.stu-prose pre, .stu-prose table, .stu-prose dl { margin: 0 0 1rem; }
.stu-prose :is(h1, h2, h3, h4, h5, h6) { margin: 1.5rem 0 1rem; font-weight: 600; line-height: 1.25; }
.stu-prose h1 { font-size: 2rem; }
.stu-prose h2 { font-size: 1.5rem; }
.stu-prose h3 { font-size: 1.25rem; }
.stu-prose h4 { font-size: 1rem; }
.stu-prose h5 { font-size: 0.875rem; }
.stu-prose h6 { font-size: 0.85rem; color: var(--stu-muted, #6b7280); }
/* GitHub's underline under the top two heading levels. */
.stu-prose h1, .stu-prose h2 { padding-bottom: 0.3em; border-bottom: 1px solid rgba(128,128,128,0.2); }
.stu-prose ul, .stu-prose ol { padding-left: 2rem; }
.stu-prose li + li { margin-top: 0.25rem; }
.stu-prose li > p { margin-top: 1rem; }
/* Task lists: drop the bullet so it reads as a checkbox, and custom-draw the box so a
   checked item is the brand fill with a white check, in both light and dark. */
.stu-prose li.task-list-item { list-style: none; }
/* Pull the task list left so a checkbox lines up where a bullet would sit. Works nested too. */
.stu-prose ul.contains-task-list { margin-left: -1.05em; }
.stu-prose input[type="checkbox"] { appearance: none; -webkit-appearance: none; opacity: 1;
    width: 1.1em; height: 1.1em; margin: 0 0.4em 0 0; vertical-align: -0.15em; cursor: default;
    border: 1px solid var(--stu-border, rgba(128,128,128,0.4)); border-radius: 0.25rem;
    background: var(--stu-surface, #fff); position: relative; }
.stu-prose input[type="checkbox"]:checked { background: var(--stu-primary, #2563eb);
    border-color: var(--stu-primary, #2563eb); }
.stu-prose input[type="checkbox"]:checked::after { content: ""; position: absolute;
    left: 0.3em; bottom: 0.2em; width: 0.4em; height: 0.8em;
    border: solid var(--stu-on-primary, #fff); border-width: 0 2px 2px 0; transform: rotate(45deg); }
.stu-prose blockquote { padding: 0 1rem; color: var(--stu-muted, #6b7280);
    border-left: 0.25rem solid var(--stu-border, rgba(128,128,128,0.25)); }
/* Opt the CTA button out of prose link styling: `.stu-prose a` (0,1,1) outweighs
   `.stu-button` (0,1,0), so without this it repaints the button's text color and adds the
   hover underline. Authors can't override it inline, the markdown sanitizer strips style
   from anchors. Any other plain anchor that must escape prose link styling joins this list. */
.stu-prose a:not(.stu-button) { color: var(--stu-link, #2563eb); text-decoration: none; }
.stu-prose a:not(.stu-button):hover { text-decoration: underline; }
.stu-prose img { max-width: 100%; height: auto; border-radius: var(--stu-radius, 8px); }
/* A blank line the author added between two blocks (e.g. after an image) serialises to a
   standalone <br> that lands as a direct child of the markdown body. It collapses to nothing
   on publish while the editor still shows it. A <br> cannot be sized (the browser gives it no
   box even at display:block), so hide the break and put a line's worth of space on the block
   after it. Padding, not margin, so it survives margin-collapse and stays additive before a
   heading that already has its own top margin. Covers every markdown body: docs, posts, legal,
   cards. A line break inside text sits in <p>/<li>, so it is never a direct child and is missed. */
.stu-prose > br, .stu-card__body > br { display: none; }
.stu-prose > br + *, .stu-card__body > br + * { padding-top: 1.5rem; }
/* Post banner: full column width, same 16:9 art as the blog card. */
.stu-post__cover { display: block; width: 100%; aspect-ratio: 16 / 9; object-fit: cover;
    background-color: #e9e5dc; border-radius: var(--stu-radius, 8px); margin-bottom: 1.5rem; }
.stu-prose code { font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
    font-size: 0.875em; padding: 0.2em 0.4em; background: rgba(128,128,128,0.12);
    border-radius: 0.25rem; }
.stu-prose pre { overflow-x: auto; background: rgba(128,128,128,0.1); padding: 1rem;
    border-radius: var(--stu-radius, 8px); line-height: 1.45; }
.stu-prose pre code { padding: 0; background: none; font-size: 0.875rem; }
.stu-prose hr { height: 1px; border: 0; background: rgba(128,128,128,0.25); margin: 1.5rem 0; }
.stu-prose table { border-collapse: collapse; width: 100%; font-size: 0.95rem; }
.stu-prose th, .stu-prose td { border: 1px solid rgba(128,128,128,0.25); padding: 0.5rem 0.75rem;
    text-align: left; vertical-align: top; }
.stu-prose th { background: rgba(128,128,128,0.08); font-weight: 700; }
.stu-docs-toggle { display: none; }
.stu-docs-burger { display: none; }
@media (max-width: 640px) {
    .stu-docs { flex-direction: column; }
    .stu-docs-burger { display: block; margin: 1rem 1.5rem 0; padding: 0.5rem 0.75rem;
        border: 1px solid rgba(128,128,128,0.25); border-radius: var(--stu-radius, 8px);
        font-weight: 600; cursor: pointer; }
    .stu-docs__sidebar { display: none; position: static; width: 100%; flex-basis: auto;
        max-height: none; border-right: 0; border-bottom: 1px solid rgba(128,128,128,0.2); }
    .stu-docs__sidebar-inner { position: static; max-height: none; overflow: visible;
        padding: 1rem 1.5rem; }
    .stu-docs__nav { overflow: visible; }
    .stu-docs-toggle:checked ~ .stu-docs__sidebar { display: block; }
    .stu-docs__article { padding: 1.5rem; }
}

/* Game: transparent bar overlaid on the hero above the fold. */
.stu-header--game { position: absolute; top: 0; left: 0; right: 0;
    background: transparent; border-bottom: 0; }

/* Mobile menu: a checkbox toggles the dropdown, no JavaScript. */
.stu-nav-toggle { display: none; }
.stu-nav-burger { display: none; flex-direction: column; gap: 0.25rem; padding: 0.5rem; cursor: pointer; }
.stu-nav-burger span { display: block; width: 1.375rem; height: 2px; background: currentColor; }

@media (max-width: 640px) {
    .stu-col--stack { flex-basis: 100%; }

    /* Mobile align override. Emitted only when the element sets a mobile align, and it wins
       here because these rules come after the desktop align rules in source order. */
    .stu-align-left-m { text-align: left; }
    .stu-align-center-m { text-align: center; }
    .stu-align-right-m { text-align: right; }
    .stu-align-left-m img, .stu-align-left-m .stu-video { margin-left: 0; margin-right: auto; }
    .stu-align-center-m img, .stu-align-center-m .stu-video { margin-left: auto; margin-right: auto; }
    .stu-align-right-m img, .stu-align-right-m .stu-video { margin-left: auto; margin-right: 0; }
    .stu-align-left-m .stu-btn-row { justify-content: flex-start; }
    .stu-align-center-m .stu-btn-row { justify-content: center; }
    .stu-align-right-m .stu-btn-row { justify-content: flex-end; }

    .stu-nav-burger { display: flex; }
    .stu-nav { display: none; position: absolute; top: 100%; left: 0; right: 0;
        flex-direction: column; align-items: flex-start; gap: 0;
        background: var(--stu-background, #ffffff); padding: 1rem 1.5rem;
        border-bottom: 1px solid rgba(128,128,128,0.2); }
    .stu-nav-toggle:checked ~ .stu-nav { display: flex; }
    .stu-nav__link { height: 2.5rem; width: calc(100% + 1.5rem); display: flex; align-items: center;
        margin: 0 -0.75rem; padding: 0 0.75rem; box-sizing: border-box; border-radius: var(--stu-radius, 8px); }
    .stu-nav__cta { margin-left: 0; margin-top: 0.5rem; }
    .stu-header--game .stu-nav { background: var(--stu-background, #0d191f); }
}