/* ===========================================
   PineRoster page grammar (ADR-003)
   -------------------------------------------
   JOB: one layout vocabulary for every buyer page. Loaded AFTER styles.css,
   which keeps ownership of the palette, the type stacks, the header, the
   footer, forms, alerts, buttons and blog content. This file adds only the
   `studio-*` structure: intro, sections, split prose, numbered rows, framed
   product captures, one closing invitation.

   INVARIANTS a maintainer must not break:
   1. No colour literals. Every colour here is an existing custom property
      from the two token blocks at the top of styles.css, so ADR-001's
      palette stays the single source of truth and dark mode comes free.
      The two exceptions are `#fff` and a translucent white, used only on
      the deep-pine .studio-cta band, which is the same light-on-pine
      pattern .hero and .section-dark already use.
   2. .btn-primary is not touched. Gold fill with dark ink is a permanent
      brand rule (ADR-001); this file never restyles it.
   3. The class names are deliberately identical to Dirt River Design's
      css/visual-refresh.css. The two sites are meant to share one layout
      vocabulary, so a fix to a shape here has an obvious twin over there.
   4. Geometry only: nothing here reveals content on scroll, and nothing
      depends on JavaScript.

   FAILURE BEHAVIOR: if this stylesheet fails to load the pages still read
   top to bottom in document order, because every section is a plain
   <section>/<div> with real headings and no absolute positioning.
   =========================================== */

/* --- Skip link -----------------------------------------------------------
   JOB: the first thing in the tab order on every page is a way past the
   header, so a keyboard or screen-reader visitor is not made to walk seven
   nav items on every route before reaching the content.

   It is the one element on this site deliberately kept out of sight while
   unfocused, and it is CLIPPED rather than hidden: display:none and
   visibility:hidden both remove an element from the tab order, and a skip
   link that cannot be focused is not a skip link. The 1px clipped box sits
   at the document origin rather than at a negative offset, because a
   negative offset is indistinguishable from a real horizontal-overflow bug
   to any tool measuring bounding boxes.

   Its target is <main id="main" tabindex="-1"> in includes/header.php. The
   tabindex is load-bearing: without it the fragment jump moves the scroll
   position but leaves focus on <body>, and the next Tab starts again at the
   top of the header. Do not remove one without the other.

   Colours: gold fill with dark ink, the permanent brand pairing (ADR-001,
   never white on gold), measured 6.21:1 light and 7.86:1 dark. The focus
   outline is --color-primary against the page behind the pill, 7.93:1 light
   and 9.33:1 dark.

   FAILURE BEHAVIOR: without this stylesheet the link is an ordinary visible
   link at the top of every page. Uglier, still correct. */
.skip-link {
    position: absolute;
    top: 0;
    left: 0;
    width: 1px;
    height: 1px;
    padding: 0;
    border: 0;
    overflow: hidden;
    clip: rect(0 0 0 0);
    clip-path: inset(50%);
    white-space: nowrap;
}

.skip-link:focus {
    position: fixed;
    top: 1rem;
    left: 1rem;
    z-index: 1000;
    width: auto;
    height: auto;
    padding: 0.7rem 1.15rem;
    overflow: visible;
    clip: auto;
    clip-path: none;
    background: var(--color-accent);
    color: var(--color-btn-ink);
    border-radius: var(--border-radius);
    box-shadow: var(--shadow);
    font-size: 0.95rem;
    font-weight: 600;
    text-decoration: none;
    outline: 3px solid var(--color-primary);
    outline-offset: 3px;
}

/* --- Header: the last nav item is the demo button ------------------------
   Only above the 1310px mobile-nav breakpoint set in styles.css; inside the
   dropdown it stays an ordinary full-width row. Gold with dark ink, the same
   pairing as .btn-primary. */
@media (min-width: 1311px) {
    header nav a.nav-demo {
        background: var(--color-accent);
        color: var(--color-btn-ink);
        padding: 0.45rem 0.95rem;
        border-radius: var(--border-radius);
        font-weight: 600;
    }

    header nav a.nav-demo:hover {
        background: var(--color-accent-hover);
        color: var(--color-btn-ink);
    }

    header nav a.nav-demo::after {
        display: none;
    }
}

/* --- Home hero ---------------------------------------------------------- */
.studio-hero {
    padding: clamp(2.75rem, 5vw, 4rem) 0 0;
    overflow: hidden;
}

.studio-hero-grid {
    display: grid;
    grid-template-columns: 1fr 1.05fr;
    gap: clamp(2rem, 4vw, 3.5rem);
    align-items: center;
}

.studio-hero-grid > * {
    min-width: 0;
}

.studio-kicker {
    font-size: 0.78rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.12em;
    color: var(--color-primary);
    margin: 0 0 1.2rem;
}

.studio-intro h1 {
    font-family: var(--font-family-heading);
    font-size: clamp(2.4rem, 4.2vw, 4rem);
    line-height: 1.08;
    letter-spacing: -0.02em;
    margin: 0 0 1.4rem;
}

.studio-lede {
    color: var(--color-muted);
    font-size: 1.1rem;
    line-height: 1.7;
    max-width: 46ch;
    margin: 0 0 1.9rem;
}

.studio-actions {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 1.25rem 1.6rem;
}

.studio-text-link {
    color: var(--color-text);
    display: inline-flex;
    gap: 0.6rem;
    align-items: center;
    font-size: 0.95rem;
    font-weight: 600;
    border-bottom: 1px solid var(--color-border);
    padding-bottom: 0.3rem;
}

.studio-text-link:hover {
    color: var(--color-hover);
    border-color: var(--color-primary);
}

/* --- Framed product capture ---------------------------------------------
   One frame per screen, never rotated, never cropped: the whole capture is
   shown at its own aspect ratio so nothing in the product is hidden by the
   layout. The caption strip names what the picture is. */
.studio-showcase {
    min-width: 0;
}

.studio-site {
    display: block;
    margin: 0;
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--border-radius);
    overflow: hidden;
    box-shadow: var(--shadow);
}

.studio-site img {
    display: block;
    width: 100%;
    height: auto;
}

.studio-browser-bar {
    display: flex;
    align-items: center;
    gap: 0.65rem;
    padding: 0.6rem 0.85rem;
    color: var(--color-muted);
    font-size: 0.72rem;
    background: var(--color-surface);
    border-bottom: 1px solid var(--color-border);
}

.studio-browser-bar i {
    flex-shrink: 0;
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: var(--color-border);
    box-shadow: 10px 0 var(--color-border), 20px 0 var(--color-border);
    margin-right: 1.2rem;
}

/* The provenance line rides inside the frame, under the picture, so a reader
   who screenshots or shares one of these cannot separate the product shot
   from the fact that its data is fictional. */
.studio-site .studio-showcase-caption {
    font-size: 0.78rem;
    line-height: 1.4;
    color: var(--color-muted);
    background: var(--color-surface);
    border-top: 1px solid var(--color-border);
    padding: 0.55rem 0.85rem;
    margin: 0;
}

/* --- Click to enlarge a capture -----------------------------------------
   JOB: let a reader open any framed capture at full size, because a 2880px
   screenshot shown at column width is unreadable and the product evidence
   is the point of the picture (ADR-003, imagery rule).

   The markup is an ordinary <a class="studio-zoom" href="[the same image]">
   wrapped around the picture, so with JavaScript off the anchor opens the
   file in the tab; js/main.js upgrades the same anchor to the
   <dialog class="studio-lightbox"> styled below. The frame's browser bar
   carries the visible label that says so.

   The dialog is three stacked blocks: a toolbar naming the capture and
   holding both controls, the stage that shows it, and the caption. Nothing
   is positioned over the picture, because a control floating on a capture
   hides part of the evidence the capture exists to show.

   INVARIANT: nothing here animates, so prefers-reduced-motion has nothing
   to suppress and no motion query is needed.

   FAILURE BEHAVIOR: without this stylesheet the anchor is still a link and
   the dialog is still a modal dialog wearing the browser's own chrome. The
   one rule that needs a recent browser is the ::backdrop colour, which
   reads a custom property through its originating element; where ::backdrop
   does not inherit, the backdrop is simply transparent and the dialog still
   traps focus and still locks the page behind it. */
.studio-zoom {
    display: block;
    cursor: zoom-in;
}

/* The bar's other children sit left; this label is pushed to the far end. */
.studio-zoom-hint {
    margin-left: auto;
}

/* The page scroll lock. js/main.js sets this one class on <html> while a
   lightbox is open and removes it on close; it is the only thing the script
   needs from this file. */
html.studio-lightbox-open {
    overflow: hidden;
}

dialog.studio-lightbox {
    /* How tall the stage may be, and with it the fitted picture inside it.
       One number, because the two must agree: the toolbar and the caption
       take the rest of the dialog's height, and the whole dialog has to stay
       inside the viewport at 1366x768 and at 375x812. Raising it without
       measuring those two sizes is how the close button ends up off screen. */
    --studio-lightbox-stage: calc(88vh - 5rem);
    padding: 0;
    overflow: hidden;
    background: var(--color-surface);
    color: var(--color-text);
    border: 1px solid var(--color-border);
    border-radius: var(--border-radius);
    /* The user-agent sheet caps a dialog at calc(100% - 6px - 2em), which on
       a phone would leave the full-width mobile frame below stranded. The
       stage below does the real limiting. */
    max-width: 100vw;
    max-height: 100vh;
}

dialog.studio-lightbox::backdrop {
    background: color-mix(in srgb, var(--color-primary-strong) 86%, transparent);
}

/* --- The dialog's toolbar ------------------------------------------------
   Sits above the picture, never on it. The close button used to float on the
   capture's top-right corner, where it covered the engine's own Log out
   button in the map capture.

   Both controls are at least 44x44 CSS px, the phone touch-target floor, and
   the row wraps rather than pushing either of them off the edge. */
.studio-lightbox-bar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem 0.75rem;
    padding: 0.5rem 0.6rem;
    background: var(--color-surface);
    border-bottom: 1px solid var(--color-border);
}

/* The capture's own name, taken from the frame's browser bar by js/main.js. */
.studio-lightbox-title {
    margin: 0;
    min-width: 0;
    font-size: 0.85rem;
    font-weight: 600;
    line-height: 1.3;
    color: var(--color-text);
}

.studio-lightbox-tools {
    display: flex;
    align-items: center;
    gap: 0.5rem;
}

.studio-lightbox-toggle,
.studio-lightbox-close {
    min-width: 44px;
    min-height: 44px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    line-height: 1;
    cursor: pointer;
    background: var(--color-surface);
    color: var(--color-text);
    border: 1px solid var(--color-border);
    border-radius: var(--border-radius);
}

.studio-lightbox-toggle {
    padding: 0 0.8rem;
    font-family: inherit;
    font-size: 0.85rem;
    font-weight: 600;
}

.studio-lightbox-close {
    padding: 0;
    font-size: 1.5rem;
}

.studio-lightbox-toggle:hover,
.studio-lightbox-close:hover {
    background: var(--color-surface-2);
}

/* --- The stage -----------------------------------------------------------
   THE RULE, learned from the sibling site: a scroll container may not centre
   content it is allowed to overflow. place-items: center, an auto margin or
   a negative offset all put the start of a too-wide picture at a negative x,
   where no amount of scrolling can bring it back.

   So the two modes are deliberately asymmetric. Fit mode may centre, because
   nothing overflows there. Full-size mode aligns to the start and offsets
   nothing, so the picture's left edge is the stage's own content edge and
   scrolling reaches every pixel of it. */
.studio-lightbox-stage {
    max-height: var(--studio-lightbox-stage);
    overflow: hidden;
    background: var(--color-surface);
}

.studio-lightbox-image {
    display: block;
    width: auto;
    height: auto;
    /* Fit mode only: the picture is narrower than the dialog when the caption
       or the toolbar is the wider child, and it is centred there. */
    margin-inline: auto;
    max-width: min(96vw, 1800px);
    max-height: var(--studio-lightbox-stage);
    object-fit: contain;
}

/* Full size: the capture at the file's own pixels, which js/main.js sets as
   a width in px from naturalWidth. The stage scrolls both ways to reach it,
   and the start-aligned picture keeps its left edge at x >= 0. */
dialog.studio-lightbox.is-full-size .studio-lightbox-stage {
    overflow: auto;
}

dialog.studio-lightbox.is-full-size .studio-lightbox-image {
    margin-inline: 0;
    max-width: none;
    max-height: none;
}

.studio-lightbox-caption {
    font-size: 0.85rem;
    line-height: 1.4;
    color: var(--color-muted);
    background: var(--color-surface);
    border-top: 1px solid var(--color-border);
    padding: 0.6rem 0.85rem;
    margin: 0;
}

/* --- The three-fact strip under the home hero --------------------------- */
.studio-discipline-strip {
    border-top: 1px solid var(--color-border);
    border-bottom: 1px solid var(--color-border);
    margin-top: clamp(2.5rem, 5vw, 4rem);
}

.studio-discipline-strip .container {
    display: flex;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: 1rem 2rem;
    padding-block: 1.4rem;
}

.studio-discipline-strip span {
    font-size: 0.95rem;
    font-weight: 600;
}

/* The mark is generated content, which means it is a rendered text glyph and
   is held to the text threshold, not to the 3:1 non-text one. In gold it
   measured 2.29:1 on the paper canvas, so it is set in --color-primary:
   7.93:1 light, 9.33:1 dark. Owner-directed 2026-09-07. */
.studio-discipline-strip span::before {
    content: '+';
    color: var(--color-primary);
    margin-right: 0.8rem;
    font-weight: 700;
}

/* --- Sections ----------------------------------------------------------- */
.studio-section {
    padding: clamp(3.5rem, 6vw, 5.5rem) 0;
    scroll-margin-top: 5rem;
}

.studio-tinted {
    background: var(--color-surface-2);
}

.studio-section h2 {
    font-size: clamp(1.9rem, 3vw, 2.6rem);
    line-height: 1.14;
    margin: 0;
}

.studio-section-heading {
    display: flex;
    justify-content: space-between;
    align-items: flex-end;
    gap: clamp(1.5rem, 4vw, 3rem);
    margin-bottom: 2.75rem;
}

.studio-section-heading > * {
    min-width: 0;
}

.studio-section-heading > div > h2 {
    margin-bottom: 0;
}

.studio-section-heading > p {
    max-width: 38ch;
    color: var(--color-muted);
    font-size: 1.02rem;
    line-height: 1.7;
    margin: 0 0 0.25rem;
}

.studio-split {
    display: grid;
    grid-template-columns: 1fr 1.15fr;
    gap: clamp(2rem, 5vw, 5rem);
    align-items: start;
}

.studio-split > * {
    min-width: 0;
}

.studio-split h2 {
    margin-bottom: 1.5rem;
}

.studio-prose {
    max-width: 66ch;
}

/* When the prose measure IS the container (the FAQ), capping the container
   itself would centre the column and give the page a second left edge, out
   of line with the h1 above it. Keep the container where it is and cap each
   block inside it instead. */
.container.studio-prose {
    max-width: var(--container-width);
}

.container.studio-prose > * {
    max-width: 66ch;
}

.studio-prose p,
.studio-case-copy > p:not(.studio-kicker) {
    color: var(--color-muted);
}

.studio-prose h3 {
    margin-top: var(--space-lg);
}

.studio-prose h3:first-child {
    margin-top: 0;
}

/* Plain ruled list. Used wherever a section is a short inventory of facts
   rather than prose: what is included, what is left out, what recurs. */
.studio-list {
    list-style: none;
    padding: 0;
    margin: 0 0 var(--space-lg);
    max-width: 66ch;
    border-top: 1px solid var(--color-border);
}

.studio-list li {
    margin: 0;
    padding-block: 0.7rem;
    border-bottom: 1px solid var(--color-border);
    color: var(--color-muted);
    font-size: 0.95rem;
    line-height: 1.55;
}

/* --- Numbered rows ------------------------------------------------------ */
.studio-service-list {
    border-top: 1px solid var(--color-border);
}

.studio-service-row {
    display: grid;
    grid-template-columns: 2.25rem 1fr 1.9fr;
    gap: 2rem;
    padding-block: 2rem;
    border-bottom: 1px solid var(--color-border);
    align-items: start;
}

.studio-number {
    font-family: var(--font-family-mono);
    color: var(--color-primary);
    font-size: 0.8rem;
    font-weight: 700;
    letter-spacing: 0.06em;
    line-height: 1.9;
}

/* Listing rows may carry an h2 (the blog index: h1 then one h2 per post, no
   level jump) and get the same size as the h3 rows everywhere else. */
.studio-service-row h3,
.studio-section .studio-service-row h2 {
    font-size: 1.35rem;
    line-height: 1.25;
    margin: 0;
}

.studio-service-row p {
    color: var(--color-muted);
    font-size: 0.98rem;
    margin: 0;
}

.studio-service-row p + p {
    margin-top: var(--space-sm);
}

/* A numbered list living inside one half of a split has roughly half the
   room, so it stacks its heading over its paragraph at every width instead
   of holding three columns open in 500px. */
.studio-split .studio-service-row {
    grid-template-columns: 2rem 1fr;
    gap: 0.5rem 1rem;
    padding-block: 1.5rem;
}

.studio-split .studio-service-row > div {
    grid-column: 2;
}

/* --- Three-step process ------------------------------------------------- */
.studio-process {
    list-style: none;
    padding: 0;
    margin: 0;
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 2rem;
}

.studio-process li {
    border-top: 1px solid var(--color-border);
    padding-top: 1.25rem;
    margin: 0;
}

.studio-process h3 {
    font-size: 1.15rem;
    margin: 0 0 var(--space-xs);
}

.studio-process p {
    color: var(--color-muted);
    font-size: 0.95rem;
    margin: 0;
}

/* Same reasoning as the numbered rows: three steps side by side inside half a
   split is roughly 160px per column, which is not a column, it is a stack of
   two-word lines. In a split the steps run down the page. */
.studio-split .studio-process {
    grid-template-columns: 1fr;
    gap: 1.5rem;
}

/* --- Alternating capture rows ------------------------------------------- */
.studio-case {
    display: grid;
    grid-template-columns: 1.25fr 1fr;
    align-items: center;
    gap: clamp(2rem, 4vw, 4rem);
    padding-block: clamp(2.5rem, 4vw, 3.5rem);
    border-bottom: 1px solid var(--color-border);
}

.studio-case:last-child {
    border-bottom: 0;
    padding-bottom: 0;
}

.studio-case:nth-child(even) .studio-case-image {
    order: 2;
}

.studio-case-image {
    min-width: 0;
}

.studio-case-copy {
    min-width: 0;
}

.studio-case-copy h2 {
    font-size: clamp(1.6rem, 2.2vw, 2rem);
    margin: 0 0 var(--space-sm);
}

.studio-case-copy .studio-case-lede {
    color: var(--color-muted);
    font-size: 1.02rem;
    line-height: 1.65;
    margin: 0;
}

/* --- Closing invitation ------------------------------------------------- */
/* Deep pine band with light text in both themes, which is the same
   light-on-pine pairing .hero and footer already use. Measured with the
   relative-luminance script: white on --color-primary-strong is 12.80:1
   light / 9.72:1 dark, the gold kicker 4.91:1 / 4.71:1. */
.studio-cta {
    background: var(--color-primary-strong);
    color: #fff;
}

.studio-cta h2 {
    color: #fff;
    margin-bottom: var(--space-md);
}

.studio-cta .studio-kicker {
    color: var(--color-accent);
}

.studio-cta p:not(.studio-kicker) {
    max-width: 48ch;
    color: rgba(255, 255, 255, 0.88);
    margin-bottom: 0;
}

.studio-cta .studio-section-heading {
    align-items: center;
    margin-bottom: 0;
}

.studio-cta-action {
    flex-shrink: 0;
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 1.25rem 1.6rem;
}

.studio-cta .studio-text-link {
    color: #fff;
    border-color: rgba(255, 255, 255, 0.45);
}

.studio-cta .studio-text-link:hover {
    color: #fff;
    border-color: var(--color-accent);
}

/* The invitation band is the last section on every page that has one, and the
   footer's own 4rem top margin then paints a sliver of paper between two dark
   blocks, which reads as a mistake. Written as the real condition rather than
   a hand-maintained list of page classes; a browser without :has() keeps the
   gap, which is today's behaviour and not a regression. */
main:has(> .studio-cta) + footer {
    margin-top: 0;
}

/* --- Page intro (every page except the home page) ----------------------- */
.studio-page-intro {
    border-bottom: 1px solid var(--color-border);
}

.studio-page section.studio-page-intro {
    padding-block: clamp(2.75rem, 5vw, 4rem);
}

.studio-page-intro h1 {
    font-family: var(--font-family-heading);
    font-size: clamp(2.2rem, 3.6vw, 3.4rem);
    line-height: 1.1;
    letter-spacing: -0.02em;
    max-width: 24ch;
    margin: 0 0 1.25rem;
}

.studio-page-intro .studio-lede {
    max-width: 64ch;
}

.studio-page-intro .studio-lede:last-child {
    margin-bottom: 0;
}

/* --- About -------------------------------------------------------------- */
.studio-about-intro {
    display: grid;
    grid-template-columns: 1.7fr 0.8fr;
    gap: clamp(2rem, 5vw, 4rem);
    align-items: center;
}

.studio-about-intro > * {
    min-width: 0;
}

.about-headshot {
    width: 100%;
    max-width: 280px;
    height: auto;
    border-radius: var(--border-radius-lg);
    display: block;
    justify-self: end;
}

/* --- Contact ------------------------------------------------------------ */
.studio-page .contact-info {
    background: var(--color-surface-2);
    border: 1px solid var(--color-border);
    border-radius: var(--border-radius-lg);
    padding: var(--space-lg);
}

.studio-contact-portrait {
    display: flex;
    gap: 1rem;
    align-items: center;
    margin-bottom: var(--space-md);
}

.studio-contact-portrait img {
    width: 64px;
    height: 64px;
    border-radius: 50%;
    object-fit: cover;
    flex-shrink: 0;
}

.studio-contact-portrait p {
    margin: 0;
    font-size: 0.9rem;
    color: var(--color-muted);
}

.studio-contact-portrait strong {
    display: block;
    color: var(--color-text);
    font-size: 1rem;
}

/* The form is the page's job, so it takes the wider half of the split; the
   details card beside it is reference material. Scoped to a min-width query
   on purpose: a plain `.studio-contact .studio-split` rule would outrank the
   single-column stack in the max-width block below and keep two columns open
   on a phone. */
@media (min-width: 901px) {
    .studio-contact .studio-split {
        grid-template-columns: 1.45fr 1fr;
    }
}

/* --- Pricing panels ----------------------------------------------------- */
.studio-page .pricing-card {
    text-align: left;
    padding: clamp(1.5rem, 3vw, 2.5rem);
    display: flex;
    flex-direction: column;
}

.studio-page .studio-section .pricing-card h2 {
    font-size: 1.5rem;
    margin-bottom: 0;
}

.studio-page .pricing-card .card-price {
    margin-block: var(--space-sm) var(--space-md);
    font-size: clamp(2.4rem, 4vw, 3.2rem);
    line-height: 1.05;
    letter-spacing: -0.02em;
    font-family: var(--font-family-heading);
}

.studio-page .pricing-card .card-price small {
    font-size: 1rem;
    letter-spacing: 0;
}

/* The setup fee is deliberately unpublished, so that card's price line is a
   sentence rather than a number and is set at sentence size. */
.studio-page .pricing-card .card-price.studio-price-quote {
    font-family: var(--font-family);
    font-size: 1.3rem;
    font-weight: 600;
    line-height: 1.4;
    letter-spacing: 0;
}

.studio-page .pricing-card .studio-list {
    flex: 1;
}

.studio-page .pricing-card .btn {
    align-self: flex-start;
}

/* --- FAQ ---------------------------------------------------------------- */
.studio-page .faq-item {
    border-bottom: 1px solid var(--color-border);
    padding-block: var(--space-md);
    background: none;
    border-radius: 0;
}

.studio-page .studio-section .faq-item h2 {
    font-size: 1.25rem;
    line-height: 1.35;
    margin-bottom: var(--space-xs);
}

.studio-page .faq-item p {
    color: var(--color-muted);
    margin-bottom: 0;
}

/* --- Blog listing rows -------------------------------------------------- */
.studio-post-meta {
    color: var(--color-muted);
    font-size: 0.9rem;
    margin: 0 0 var(--space-xs);
}

.studio-pagination {
    display: flex;
    justify-content: center;
    align-items: center;
    flex-wrap: wrap;
    gap: var(--space-sm);
    margin-top: var(--space-xl);
}

.studio-pagination .btn {
    width: auto;
    padding: var(--space-xs) var(--space-md);
}

.studio-pagination span {
    color: var(--color-muted);
}

/* ADR-002 set the post body to a ~62ch measure and that judgement still
   holds; the rail it lived on is what ADR-003 retired, not the measure. The
   reading container is 1000px, which would otherwise run the body past 100
   characters a line. */
.studio-post .blog-content {
    max-width: 68ch;
}

.studio-page .blog-cta {
    margin-top: var(--space-xxl);
}

/* --- Focus ring --------------------------------------------------------- */
.studio-page a:focus-visible,
.studio-page button:focus-visible {
    outline: 3px solid var(--color-primary);
    outline-offset: 4px;
}

.studio-page .studio-cta a:focus-visible {
    outline-color: var(--color-accent);
}

/* --- Responsive --------------------------------------------------------- */
@media (max-width: 1000px) {
    .studio-service-row {
        grid-template-columns: 2rem 1fr 1.5fr;
        gap: 1.5rem;
    }

    .studio-process {
        grid-template-columns: 1fr;
        gap: 1.5rem;
    }
}

@media (max-width: 900px) {
    .studio-hero {
        padding-top: 2.25rem;
    }

    .studio-hero-grid,
    .studio-split,
    .studio-case,
    .studio-about-intro {
        grid-template-columns: 1fr;
        gap: 2rem;
    }

    .studio-case:nth-child(even) .studio-case-image {
        order: 0;
    }

    .studio-section-heading {
        align-items: flex-start;
        flex-direction: column;
        gap: 1.25rem;
        margin-bottom: 2rem;
    }

    .studio-section-heading > p {
        max-width: 55ch;
    }

    .studio-discipline-strip .container {
        flex-direction: column;
        gap: 0.7rem;
    }

    .about-headshot {
        justify-self: start;
        max-width: 220px;
    }
}

@media (max-width: 600px) {
    .studio-service-row {
        grid-template-columns: 1.75rem 1fr;
        gap: 0.6rem 1rem;
    }

    .studio-service-row > div {
        grid-column: 2;
    }

    .studio-actions,
    .studio-cta-action {
        flex-direction: column;
        align-items: stretch;
        gap: 1rem;
    }

    .studio-actions .studio-text-link,
    .studio-cta-action .studio-text-link {
        align-self: flex-start;
    }

    .studio-lede {
        max-width: none;
    }

    /* On a phone the enlarged capture takes the whole width, and the height
       the stage is allowed is whatever the toolbar and the caption leave. */
    dialog.studio-lightbox {
        --studio-lightbox-stage: calc(100vh - 12rem);
        width: 100vw;
        border-radius: 0;
        border-left: 0;
        border-right: 0;
    }

    /* Fit mode only. Full size is deliberately untouched here: its width is
       the file's own pixels, and clamping it to the phone's width is exactly
       the unreadable picture the toggle exists to escape. */
    dialog.studio-lightbox:not(.is-full-size) .studio-lightbox-image {
        width: 100%;
        max-width: 100%;
    }
}
