:root {
  --maroon: #7A121C;
  --ink: #222;
  --muted: #666;
  --line: #e3e3e3;
  --bg: #fff;
  --soft: #f6f4f2;
  --freshie: #2E7D32;
  --upperclass: #1565C0;
}
* { box-sizing: border-box; }
body {
  margin: 0;
  font: 16px/1.6 system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  color: var(--ink);
  background: var(--bg);
}
/* Headings set their own line-height. 1.6 is a body measure: at 24-34px it opens a gap
   inside a wrapped heading wide enough that the two lines stop reading as one phrase.
   Space around a heading comes from its margins instead, where it belongs. */
h1, h2, h3, h4, h5, h6 { line-height: 1.2; }

.container { max-width: 880px; margin: 0 auto; padding: 0 20px; }
/* Large screens get the wider column; below this the 880px measure is kept. */
@media (min-width: 1200px) {
  .container { max-width: 1200px; }
}
a { color: var(--maroon); }

.internal-banner { background: #3a2d00; color: #ffe9a6; font-size: 13px; text-align: center; padding: 7px 16px; }
.internal-banner a { color: #fff; font-weight: 600; }

.site-header { border-bottom: 3px solid var(--maroon); }
.header-inner { display: flex; align-items: center; justify-content: space-between; padding: 14px 20px; flex-wrap: wrap; gap: 10px; }
.brand { text-decoration: none; color: var(--ink); display: flex; align-items: center; line-height: 1.2; }
.brand-logo { height: 40px; width: auto; display: block; }
.header-seals { display: flex; align-items: center; gap: 16px; flex-wrap: wrap; }
.header-seals a { display: inline-flex; line-height: 0; }
.header-seals img { height: 40px; width: auto; display: block; }
.header-seals img.seal-ovcsa { height: 22px; }
.site-nav { background: var(--soft); border-bottom: 1px solid var(--line); }
.site-nav-inner { display: flex; flex-wrap: wrap; align-items: center; justify-content: center; gap: 4px 22px; padding-top: 10px; padding-bottom: 10px; }
.site-nav a { text-decoration: none; font-weight: 600; font-size: 15px; color: var(--ink); }
.site-nav a:hover { color: var(--maroon); }
.site-nav a.is-active { color: var(--maroon); box-shadow: inset 0 -3px 0 var(--maroon); padding-bottom: 4px; }

main.container { padding-top: 32px; padding-bottom: 48px; }

.hero { background: var(--soft); border-left: 4px solid var(--maroon); padding: 28px; border-radius: 6px; margin-bottom: 28px; }
.hero h1 { margin: 0 0 6px; color: var(--maroon); }
.tagline { color: var(--muted); margin: 0 0 16px; }
.btn { display: inline-block; background: var(--maroon); color: #fff; text-decoration: none; padding: 10px 16px; border-radius: 5px; font-weight: 600;
       transition: opacity .15s, background-image .15s; }
/* Hover lightens rather than recolours: a white sheen laid over whatever the button's
   own background is, plus a touch of transparency. One rule works for any fill, so a
   button never needs a second colour picked by hand. */
.btn:hover { opacity: .92; background-image: linear-gradient(rgba(255,255,255,.18), rgba(255,255,255,0)); }
/* The press. Also on :focus-visible so a keyboard gets the same mark — outside the
   button, since the fill leaves no room for it inside. */
.btn:active, .btn:focus-visible { outline: 2px solid var(--maroon); outline-offset: 2px; }

/* Home banner. Same idea as the residence-hall hero, but the panel is white rather than
   black — it stands in for the block of text in the current artwork, so it keeps that
   text's colours: maroon heading, ink body. */
.home-hero { position: relative; margin-bottom: 28px; }
/* Whole, uncropped, whatever its shape: with no text over it the picture is doing all the
   work — today that means the composite artwork, whose own wording would be sliced off by
   a crop. */
.home-hero-bg { display: block; width: 100%; height: auto; border-radius: 8px; }
/* Once there IS text over it the picture is a background, so it gets a banner's proportions
   instead of the uploaded file's — otherwise a tall photo makes a banner you have to scroll
   past. Same treatment as the residence-hall hero. */
.home-hero.has-text .home-hero-bg { height: clamp(260px, 30vw, 400px); object-fit: cover; }
/* Sits where the wording sits in the artwork today: left-hand side, vertically centred. */
.home-hero-box { position: absolute; left: 4%; top: 50%; transform: translateY(-50%);
                 width: min(46%, 520px); padding: 20px 24px; border-radius: 8px;
                 background: rgba(255,255,255,.85); }
.home-hero-box h2 { margin: 0 0 8px; color: var(--maroon); font-size: clamp(20px, 2.4vw, 30px);
                    line-height: 1.15; }
.home-hero-box p { margin: 0 0 8px; color: var(--ink); }
.home-hero-box p:last-child { margin-bottom: 0; }
/* Too narrow to hold a readable column over the picture: the panel drops below it and the
   two join into one block, the way the hall banner does. Solid there — a translucent white
   panel on a white page is not a panel at all. */
@media (max-width: 640px) {
  .home-hero.has-text .home-hero-bg { height: clamp(150px, 42vw, 220px); border-radius: 8px 8px 0 0; }
  .home-hero-box { position: static; transform: none; width: auto; padding: 14px;
                   border-radius: 0 0 8px 8px; background: var(--soft); }
}

.prose h1 { color: var(--maroon); margin: 0 0 16px; }
.prose h2 { border-bottom: 1px solid var(--line); padding-bottom: 6px; margin-top: 36px; }
.prose h3 { margin-top: 24px; color: var(--maroon); }
.prose h4 { margin: 20px 0 6px; }
.prose table { border-collapse: collapse; width: 100%; margin: 16px 0; }
.prose th, .prose td { border: 1px solid var(--line); padding: 8px 12px; text-align: left; }
.prose th { background: var(--soft); }
.prose tbody tr:nth-child(even) { background: #fafafa; }

/* Tabbed guide pages. Without JS every panel stays visible and the tab list is
   just a set of jump links, so the page still works as one long document. */
.tabs { margin-top: 28px; }
.tab-list { display: flex; flex-wrap: wrap; gap: 2px; border-bottom: 2px solid var(--line); }
.tab { padding: 10px 16px; margin-bottom: -2px; text-decoration: none; font-weight: 600;
       color: var(--muted); border-bottom: 2px solid transparent; border-radius: 5px 5px 0 0; }
.tab:hover { color: var(--maroon); background: var(--soft); }
.tab.is-active { color: var(--maroon); border-bottom-color: var(--maroon); }
.tab:focus-visible { outline: 2px solid var(--maroon); outline-offset: -2px; }
/* A tab that leaves the site. It never opens a panel, so it is a button rather than a
   tab — but a quiet one: a wash of maroon with ordinary ink on it, not the solid fill
   the page uses for its calls to action. Next to the tab labels it reads as one more
   thing in the bar rather than the loudest thing on the page. Lifted off the bar's
   border, which is what separates "goes somewhere" from "switches the view below". */
.tab-out { background: #f6e7e7; color: var(--ink); border: 1px solid #e2c6c6;
           border-radius: 5px; padding: 7px 14px; margin: 2px 0 4px 6px; align-self: center;
           transition: opacity .15s, background-image .15s; }
/* Same hover as .btn, mirrored: a light fill darkens instead of lightening. */
/* background-color is repeated because .tab:hover above sets its own and this
   element carries both classes. */
.tab-out:hover { color: var(--ink); opacity: .92; background-color: #f6e7e7;
                 background-image: linear-gradient(rgba(0,0,0,.06), rgba(0,0,0,0)); }
.tab-out:active, .tab-out:focus-visible { outline: 2px solid var(--maroon); outline-offset: 2px; }
.tab-panel[hidden] { display: none; }
/* In tab mode the panel heading just repeats the tab above it, so it is hidden —
   the tab bar names the section and is the divider. Without JS (and on paper) every
   panel shows at once and the headings come back, because there they are the only
   thing telling the sections apart. */
.tabs-js .tab-panel > h2 { display: none; }
.tabs-js .tab-panel { margin-top: 20px; }
@media print {
  .tab-list { display: none; }
  .tab-panel[hidden] { display: block; }
  .tabs-js .tab-panel > h2 { display: block; }
}

.dorm-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); gap: 16px; margin-top: 20px; }
.dorm-card { display: block; text-decoration: none; color: var(--ink); border: 1px solid var(--line); border-radius: 8px; padding: 16px; transition: box-shadow .15s; overflow: hidden; }
.dorm-card:hover { box-shadow: 0 4px 14px rgba(0,0,0,.08); }
.dorm-card-img { display: block; width: calc(100% + 32px); height: 150px; object-fit: cover; margin: -16px -16px 12px; border-radius: 8px 8px 0 0; background: var(--soft); }
.dorm-card h3 { margin: 8px 0 6px; color: var(--maroon); }

/* Banner on an ordinary page that has an `image` (not a residence hall — those get the
   full .dorm-hero treatment further down). */
.page-hero { margin-bottom: 24px; }
.page-hero img { display: block; width: 100%; height: auto; max-height: 380px; object-fit: cover; border-radius: 8px; }
.meta { color: var(--muted); font-size: 14px; }

.tag { display: inline-block; font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: .06em; color: #fff; padding: 2px 8px; border-radius: 999px; background: var(--muted); }
.tag-freshie { background: var(--freshie); }
.tag-upperclass { background: var(--upperclass); }
/* Only appears on the office-only build, where it has to be the loudest thing on the card:
   it is the one signal that what you are looking at is not on the public site. */
.tag-draft { background: #8a5300; }

/* Home tiles */
/* Shrink-wrapped to its own text and centred in the column, rather than a bar running the
   full width. `fit-content` resolves to min(max-content, available), so a long notice still
   wraps and centres instead of overflowing a narrow screen — no media query needed. */
.fb-note { background: var(--soft); border-left: 4px solid var(--maroon); padding: 12px 16px; border-radius: 0 6px 6px 0; width: fit-content; max-width: 100%; margin: 0 auto 28px; text-align: center; }
/* Editor-authored markdown, so the box holds paragraphs rather than bare text. */
.fb-note p { margin: 0; }
.fb-note p + p { margin-top: 8px; }
/* Centred as a row rather than stretched edge to edge: the buttons are square pictures, so
   stretching them to fill whatever width is left just makes them different sizes on every
   screen. Flex, not grid, so a part-full last row centres too — same reason as the
   residence-hall feature cards. */
/* align-items:flex-start, not the default stretch: a button whose caption is left out
   should end at its picture, not be padded to the height of the captioned ones and
   show an empty strip where the caption would have been. With captions on every
   button — one line each — the heights match anyway. */
.tiles { display: flex; flex-wrap: wrap; justify-content: center; align-items: flex-start;
         gap: 16px; margin-top: 8px; }
.tiles .tile { flex: 0 1 240px; max-width: 240px; }
.tile { display: flex; flex-direction: column; text-decoration: none; color: var(--ink); background: var(--soft); border: 1px solid var(--line); border-radius: 8px; overflow: hidden; transition: transform .15s, box-shadow .15s; }
.tile:hover { transform: translateY(-2px); box-shadow: 0 6px 18px rgba(0,0,0,.15); }
.tile img { display: block; width: 100%; height: auto; aspect-ratio: 1 / 1; object-fit: cover; }
.tile p { margin: 0; padding: 12px 16px; font-size: 14px; color: var(--muted); text-align: center; }

/* --- Residence-hall hero (layouts/partials/dorm-hero.html) ---
   Background photo, the square collage over it, and a translucent black panel holding
   the white title and summary — without the panel the text lands on whatever the photo
   happens to be doing there and becomes unreadable, which is exactly what it does on
   the source site. */
.dorm-hero { --hero-inset: 22px; --hero-highlight-w: min(30%, 230px);
             position: relative; display: flex; align-items: flex-end; overflow: hidden;
             min-height: clamp(260px, 32vw, 400px); margin-bottom: 28px; border-radius: 8px; background: #1b1b1b; }
.dorm-hero-bg { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
/* Taken out of the bar's flow and laid over it, so the bar stays as tall as its text
   instead of stretching to the height of the photo. */
.dorm-hero-highlight { position: absolute; z-index: 2; left: var(--hero-inset); bottom: var(--hero-inset);
                       width: var(--hero-highlight-w); height: auto; display: block;
                       border-radius: 6px; box-shadow: 0 6px 22px rgba(0,0,0,.45); }
/* The translucent black runs the full width of the hero, so it is carried by this row
   rather than by a floating box around the text. */
/* .72, not the .55 this started at: over a bright, busy photo — Centennial's and Kamia's
   are the worst — a lighter wash left the description competing with the detail behind
   it. At .72 white text clears 7:1 against anything the photo can be. */
.dorm-hero-inner { position: relative; width: 100%; display: flex; align-items: flex-start;
                   padding: 16px var(--hero-inset); background: rgba(0,0,0,.72); }
/* Clear of the collage overlapping from the left. */
.dorm-hero.has-highlight .dorm-hero-inner { padding-left: calc(var(--hero-inset) * 2 + var(--hero-highlight-w)); }
.dorm-hero-text { flex: 1 1 auto; min-width: 0; color: #fff; }
/* Lifted out of the flow so it sits in the bar's corner instead of holding a column open
   down the full height of the bar. The name reserves that corner on its own line — the
   description, which is the long part, gets the whole width. */
.dorm-hero-tags { position: absolute; top: 16px; right: var(--hero-inset); z-index: 1; text-align: right; }
.dorm-hero-text h1 { margin: 0 0 6px; padding-right: 190px; color: #fff;
                     font-size: clamp(24px, 3.2vw, 34px); line-height: 1.2; }
/* The measure cap belongs on the paragraphs, not the block: the block has to span the
   full bar so the name's reserved corner lands on the bar's right edge. White text over
   a photo is tiring to read at a 90-character measure. */
.dorm-hero-text p { margin: 0 0 8px; max-width: 68ch; color: #fff; }
.dorm-hero-text p:last-child { margin-bottom: 0; }
/* Narrow screens take the hero apart: there is no room to lay a bar and a collage over a
   photo and still have any photo left to see, so the three pieces stack as separate
   blocks — background, then the bar, then the collage — instead of overlapping. */
@media (max-width: 640px) {
  .dorm-hero { --hero-inset: 14px;
               display: flex; flex-direction: column; align-items: stretch; gap: 0;
               min-height: 0; overflow: visible; border-radius: 0; background: none; }
  /* The photo and the bar are one block — square where they meet, rounded on the
     outside — so only the collage below is a separate card. */
  .dorm-hero-bg { order: 1; position: static; height: clamp(150px, 42vw, 220px); border-radius: 8px 8px 0 0; }
  /* Off the photo the wash would render as mid-grey against the page, which white text
     cannot sit on, so the bar goes solid here.
     The extra top padding is the badge's line: it stays absolute, but this narrow the
     name cannot give up 190px of its own line to sit beside it. */
  .dorm-hero-inner { order: 2; border-radius: 0 0 8px 8px; background: #1b1b1b;
                     padding-top: calc(var(--hero-inset) + 24px); }
  .dorm-hero.has-highlight .dorm-hero-inner { padding-left: var(--hero-inset); }
  .dorm-hero-highlight { order: 3; position: static; width: 100%; max-width: 340px;
                         margin: 10px auto 0; box-shadow: none; }
  .dorm-hero-tags { top: var(--hero-inset); }
  .dorm-hero-text h1 { padding-right: 0; }
}

/* --- Residence-hall features (layouts/partials/dorm-features.html) ---
   Three to a row at most, and a part-full last row centres rather than hugging the left —
   halls carry 4 or 5 features, so the last row is nearly always part-full. That centring
   is why this is flex and not grid: `--col` is an exact width, so it doubles as the
   flex-basis (how many fit per row) and the cap (so a lone item can't stretch wide). */
.dorm-features { list-style: none; padding: 0; margin: 26px auto 8px;
                 /* 3 x 240px + 2 x 10px gap — the cap is what limits a row to three, and
                    it drops to two and then one on its own as the screen narrows. */
                 max-width: 740px;
                 display: flex; flex-wrap: wrap; justify-content: center; gap: 10px; }
/* 2 x 240px + one gap. Set by the template when there are exactly four cards. */
.dorm-features.two-up { max-width: 490px; }
.dorm-features li { flex: 0 0 240px; width: 240px; height: 72px;
                    display: flex; align-items: center; gap: 12px; font-size: 15px; font-weight: 600;
                    background: var(--soft); border: 1px solid var(--line); border-radius: 8px; padding: 12px 14px; }
/* Fixed height means the labels have to fit two lines in the 174px left beside the icon.
   They are worded to do that — check any new one against the longest here before adding
   it, and shorten rather than let the card grow. */
.dorm-features li span { line-height: 1.35; }
.feature-icon { flex: none; width: 26px; height: 26px; color: var(--maroon); }

/* --- Residence-hall info table (layouts/partials/dorm-details.html) ---
   Prefixed with .prose throughout to outrank the generic .prose table rules above:
   this one is a two-column label/value table, not a data grid, so it wants neither the
   zebra striping nor the full grid of cell borders. */
.prose table.dorm-details { width: auto; max-width: fit-content; margin: 26px auto 8px; font-size: 15px;
                            border-collapse: separate; border-spacing: 0;
                            border: 1px solid var(--line); border-radius: 8px; overflow: hidden; }
.prose table.dorm-details th, .prose table.dorm-details td {
  text-align: left; vertical-align: top; padding: 12px 16px; border: 0; border-bottom: 1px solid var(--line); }
.prose table.dorm-details tr:last-child th, .prose table.dorm-details tr:last-child td { border-bottom: 0; }
/* nowrap instead of a fixed width, so the whole table can shrink to its content. */
.prose table.dorm-details th { white-space: nowrap; background: var(--soft); color: var(--maroon); font-weight: 700; }
.prose table.dorm-details tbody tr:nth-child(even) { background: transparent; }
.prose table.dorm-details a { text-decoration: none; font-weight: 600; }
.prose table.dorm-details a:hover { text-decoration: underline; }
.dorm-details .extras-label { margin: 10px 0 2px; color: var(--muted); }
/* No amount above it (a hall that charges no lodging fee), so nothing to space away from. */
.dorm-details .extras-label:first-child { margin-top: 0; }
.dorm-details .extras { margin: 0; padding-left: 20px; color: var(--muted); }
/* Below this the two columns no longer fit side by side. */
@media (max-width: 560px) {
  .prose table.dorm-details { max-width: 100%; }
  .prose table.dorm-details th { display: block; width: auto; background: transparent;
                                 border-bottom: 0; padding-bottom: 0; }
  .prose table.dorm-details td { display: block; }
}

/* Present for screen readers, off-screen for everyone else. */
.sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
           overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }

.cards { margin-top: 40px; }
.card-list, .post-list { list-style: none; padding: 0; }
.card, .post-list li { border-top: 1px solid var(--line); padding: 14px 0; }
.card a, .post-list a { text-decoration: none; }
.card h3, .post-list h3 { margin: 0 0 2px; }
time { color: var(--muted); font-size: 14px; }
.byline { display: block; margin-bottom: 16px; }
.back { margin-top: 32px; display: flex; flex-wrap: wrap; justify-content: space-between; gap: 8px 16px; }

/* Previous / all / next through the halls (layouts/partials/dorm-pager.html). One row per
   category the hall is in, so a hall in both gets two — the rows are separated by a rule
   because otherwise two Previous links stacked above each other read as one list. Within
   a row the two hall links take the outer columns and the listing link the middle, so
   Previous and Next stay pinned to the edges however long the hall names are. */
.dorm-pager { margin-top: 40px; border-top: 1px solid var(--line); }
.pager-row { display: grid; grid-template-columns: 1fr auto 1fr; align-items: center; gap: 12px;
             padding: 14px 0; }
.pager-row + .pager-row { border-top: 1px solid var(--line); }
.dorm-pager a { text-decoration: none; border-radius: 8px; padding: 10px 14px; }
.dorm-pager a:hover { background: var(--soft); }
.pager-prev, .pager-next { display: grid; gap: 2px; min-width: 0; }
.pager-next { text-align: right; }
.pager-dir { font-size: 13px; color: var(--muted); }
.pager-name { font-weight: 600; }
.pager-all { font-weight: 600; font-size: 14px; text-align: center; }
.pager-count { color: var(--muted); font-weight: 400; }
/* Below this the three columns cannot hold two hall names and a label side by side. */
@media (max-width: 560px) {
  .pager-row { grid-template-columns: 1fr 1fr; }
  .pager-all { grid-column: 1 / -1; grid-row: 2; }
}

.site-footer { border-top: 1px solid var(--line); margin-top: 40px; padding: 24px 0; color: var(--muted); font-size: 14px; }
.site-footer a { color: var(--maroon); }
.footer-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: 24px; margin-bottom: 18px; }
.footer-grid p { margin: 0 0 4px; }
.footer-heading { font-weight: 700; color: var(--ink); }
/* Inline SVG icons expanded from :email: / :phone: / :map: / :facebook: tokens
   by layouts/partials/icons.html. Sized and coloured by the surrounding text. */
.icon { width: 1em; height: 1em; vertical-align: -0.15em; margin-right: 6px; }
.site-nav .icon { margin-right: 5px; }
.footer-list { list-style: none; padding: 0; margin: 8px 0 0; }
.footer-list li { margin: 8px 0; }
.footer-list strong { color: var(--ink); }
.footer-feed-col, .footer-feed { min-width: 0; }
/* Editor-authored column markdown. Each link the CMS inserts is its own block,
   so paragraphs carry the row spacing the old <li> list used to. */
/* ---- Editor utility classes -------------------------------------------------
   Attached from the CMS with Goldmark block attributes (see hugo.toml):

       Some text
       {.center}

       ![logo](/images/osh-logo-left.png)
       {.center .w-50}

   Scoped to editor-authored regions so these short names can't collide with
   the site's own layout classes. */
.footer-rich .left,   .prose .left   { text-align: left; }
.footer-rich .center, .prose .center { text-align: center; }
.footer-rich .right,  .prose .right  { text-align: right; }

/* Image width, as a share of the column it sits in. For an exact pixel size,
   raw HTML also works: <img src="/images/x.png" width="120"> */
.footer-rich .w-25 img,  .prose .w-25 img  { width: 25%;  height: auto; }
.footer-rich .w-50 img,  .prose .w-50 img  { width: 50%;  height: auto; }
.footer-rich .w-75 img,  .prose .w-75 img  { width: 75%;  height: auto; }
.footer-rich .w-100 img, .prose .w-100 img { width: 100%; height: auto; }

/* Lay a block's images out in an evenly spaced row — logo/seal strips. Widths
   stay natural, so pair it with a height cap if the sources differ in size. */
.footer-rich .row,   .prose .row   { display: flex; align-items: center; flex-wrap: wrap; gap: 24px; }
.footer-rich .row img, .prose .row img { width: auto; max-height: 46px; }
/* ---------------------------------------------------------------------------- */

.footer-rich p { margin: 8px 0; }
.footer-rich p:first-child { margin-top: 0; }
.footer-rich img { max-width: 100%; height: auto; }
.footer-rich ul { list-style: none; padding: 0; margin: 8px 0 0; }

/* The Page Plugin renders at the fixed pixel width passed in its URL (max 500) and
   cannot reflow — `adapt_container_width` only works via Facebook's JS SDK, which
   this site does not load. So keep the CSS cap and that width in step, or the widget
   gets clipped by its own iframe. */
.fb-feed { display: block; border: none; overflow: hidden; width: 100%; max-width: 340px; margin: 10px 0 6px; }
.footer-feed-link { font-size: 13px; }

/* --- Residence-hall photo albums --- */
.dorm-gallery { margin-top: 40px; }
.gallery-jump { display: flex; flex-wrap: wrap; justify-content: center; gap: 8px; margin: 0 0 8px; }
.gallery-jump a { text-decoration: none; font-size: 14px; font-weight: 600; background: var(--soft); border: 1px solid var(--line); border-radius: 999px; padding: 5px 12px; }
.gallery-jump a:hover { background: var(--maroon); border-color: var(--maroon); color: #fff; }
.gallery-album { scroll-margin-top: 16px; text-align: center; }
/* Flex rather than grid so a part-full last row centres instead of hugging the left —
   albums run 1-7 photos, so most rows are part-full. */
.gallery-grid { display: flex; flex-wrap: wrap; justify-content: center; align-items: flex-start; gap: 12px; margin-top: 12px; }
/* Browsers give <figure> a 40px inline margin that would wreck the layout. */
.gallery-item { margin: 0; flex: 1 1 180px; max-width: 260px; }
.gallery-item a { display: block; border-radius: 8px; overflow: hidden; }
.gallery-item a:focus-visible { outline: 2px solid var(--maroon); outline-offset: 2px; }
.gallery-item img { display: block; width: 100%; height: auto; aspect-ratio: 3 / 2; object-fit: cover; background: var(--soft); transition: transform .15s, box-shadow .15s; }
.gallery-item a:hover img { transform: scale(1.03); box-shadow: 0 4px 14px rgba(0,0,0,.08); }
.gallery-item figcaption { font-size: 14px; color: var(--muted); padding: 6px 2px 0; }

/* Lightbox. Built only once JS runs — without it the thumbnails stay plain links
   to the full-size photo, so nothing here applies. */
body.lb-open { overflow: hidden; }
/* Bar across the top, then prev / photo / next: the buttons take the outer columns
   and the photo the middle one. */
.gallery-lightbox { position: fixed; inset: 0; z-index: 50; background: rgba(0,0,0,.92); display: grid; grid-template-columns: auto 1fr auto; grid-template-rows: auto 1fr; align-items: center; gap: 8px; padding: 8px; }
.gallery-lightbox[hidden] { display: none; }
.lb-bar { grid-column: 1 / -1; display: flex; align-items: center; gap: 12px; color: #fff; padding: 4px 8px; }
/* Album name sits left and takes the slack, so the counter and close button stay put. */
.lb-album { flex: 1; min-width: 0; font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.lb-count { font-size: 14px; opacity: .8; flex: none; }
.lb-stage { grid-column: 2; margin: 0; display: grid; justify-items: center; gap: 10px; min-width: 0; }
.lb-stage img { max-width: 100%; max-height: 80vh; width: auto; height: auto; display: block; border-radius: 6px; }
.lb-caption { color: #fff; font-size: 15px; text-align: center; max-width: 60ch; }
.lb-caption[hidden] { display: none; }
.lb-btn { background: rgba(255,255,255,.12); color: #fff; border: 0; border-radius: 999px; width: 44px; height: 44px; font-size: 26px; line-height: 1; cursor: pointer; }
.lb-btn:hover { background: rgba(255,255,255,.28); }
.lb-btn:focus-visible { outline: 2px solid #fff; outline-offset: 2px; }
.lb-btn[hidden] { visibility: hidden; display: block; }
@media (max-width: 600px) { .lb-btn { width: 38px; height: 38px; font-size: 22px; } }
@media print { .gallery-lightbox { display: none; } }

/* --- Memos --- */
/* The heading and the approval line under it are the document's masthead, centred as they
   are on the issued document. The second rule takes the paragraph immediately after the
   title, which by the convention of these documents is the approval/date line — a memo
   whose text starts some other way simply doesn't match it. */
.memo > h1 { text-align: center; margin: 0 0 10px; }
.memo > h1 + p { text-align: center; color: var(--muted); margin: 0 0 30px; }

/* --- Memos: collapsible scoring tables (layouts/memos/single.html) ---
   Built to look like a control, not a heading that happens to move: a raised card with a
   boxed +/- affordance, a hover state on the whole bar, and a pointer cursor. The first
   attempt was a flat tinted strip and nobody read it as clickable. */
.criteria { border: 1px solid var(--line); border-radius: 8px; margin: 14px 0; background: var(--bg);
            box-shadow: 0 1px 2px rgba(0,0,0,.05); overflow: hidden; }
.criteria > summary { cursor: pointer; padding: 16px 18px; background: var(--soft);
                      display: flex; align-items: center; gap: 14px;
                      list-style: none; transition: background .12s; }
.criteria > summary::-webkit-details-marker { display: none; }
/* The heading is the label; the summary is the button around it. */
.criteria > summary h4 { margin: 0; font-size: 17px; color: var(--maroon); }
/* Drawn, not the browser's triangle — that renders at a different size and colour in every
   engine and is far too small to read as a target. */
.criteria > summary::before { content: "+"; flex: none; width: 28px; height: 28px; border-radius: 6px;
                              background: var(--maroon); color: #fff; font-size: 20px; font-weight: 700;
                              line-height: 28px; text-align: center; }
.criteria[open] > summary::before { content: "−"; }
.criteria > summary:hover { background: #ece5e1; }
.criteria > summary:focus-visible { outline: 2px solid var(--maroon); outline-offset: -2px; }
.criteria[open] > summary { border-bottom: 1px solid var(--line); }
/* The table is the panel body, so it drops its own outer spacing. */
.prose .criteria .criteria-body table { margin: 0; border: 0; }
.prose .criteria .criteria-body th:first-child,
.prose .criteria .criteria-body td:first-child { border-left: 0; }
.prose .criteria .criteria-body th:last-child,
.prose .criteria .criteria-body td:last-child { border-right: 0; }
.prose .criteria .criteria-body tr:last-child td { border-bottom: 0; }
/* On paper there is no "open": every panel prints, and the marker would be noise. */
@media print {
  .criteria > summary::before { display: none; }
  .criteria > summary h4 { color: var(--ink); }
}

/* --- Editor's Guide (/help/) --- */
/* Every page in the guide carries the whole guide at the top. Pills rather than a
   tab bar: this is a set of separate pages, not one page in sections, and the page
   you are on is filled in instead of underlined. */
.help-nav { display: flex; flex-wrap: wrap; gap: 6px; margin: 0 0 22px; padding-bottom: 16px;
            border-bottom: 1px solid var(--line); }
.help-nav a { font-size: 14px; font-weight: 600; text-decoration: none; color: var(--muted);
              background: var(--soft); border: 1px solid var(--line); border-radius: 999px;
              padding: 6px 12px; transition: opacity .15s, background-image .15s; }
.help-nav a:hover { color: var(--maroon); opacity: .92;
                    background-image: linear-gradient(rgba(0,0,0,.06), rgba(0,0,0,0)); }
.help-nav a[aria-current] { background: var(--maroon); border-color: var(--maroon); color: #fff; }
.help-nav a:active, .help-nav a:focus-visible { outline: 2px solid var(--maroon); outline-offset: 2px; }
@media print { .help-nav { display: none; } }
.help-lead { color: var(--muted); font-size: 17px; margin: 0 0 28px; }
/* Code samples in the guide (a table written out, the HTML for a button). The site has
   no other code blocks, so these live here. overflow-x matters: one of those lines is
   longer than the column, and without it the whole page scrolls sideways. */
.prose code { font: .9em/1.5 ui-monospace, SFMono-Regular, Menlo, monospace;
              background: var(--soft); border: 1px solid var(--line); border-radius: 4px;
              padding: 1px 5px; }
.prose pre { background: var(--soft); border: 1px solid var(--line); border-radius: 6px;
             padding: 12px 14px; overflow-x: auto; }
.prose pre code { background: none; border: 0; padding: 0; }
.flow { counter-reset: flow; list-style: none; padding: 0; margin: 0 0 8px; display: grid; gap: 14px; }
.flow li { counter-increment: flow; position: relative; padding: 16px 16px 16px 60px; background: var(--soft); border-radius: 8px; }
.flow li::before { content: counter(flow); position: absolute; left: 16px; top: 14px; width: 30px; height: 30px; border-radius: 999px; background: var(--maroon); color: #fff; font-weight: 700; display: grid; place-items: center; }
.flow li strong { display: block; }
.flow li span { color: var(--muted); font-size: 14px; }
.steps { padding-left: 22px; }
.steps li { margin: 8px 0; }
.note { border-left: 4px solid var(--maroon); background: var(--soft); padding: 12px 16px; border-radius: 0 6px 6px 0; margin: 20px 0; font-size: 15px; }
.note strong { color: var(--maroon); }
kbd { font: 13px/1 ui-monospace, SFMono-Regular, Menlo, monospace; background: #fff; border: 1px solid var(--line); border-bottom-width: 2px; border-radius: 4px; padding: 2px 6px; }
