/* =============================================================================
   base.css -- structure, type scale, the shared palette, and every component.
   theme-cinema.css / theme-outtakes.css sit on top and override ONLY what differs
   between the two brands, which since the redesign is the accent hue and the light
   it throws. They are selected by URL prefix in App.razor.

   WHY THE SHARED PALETTE LIVES HERE AND NOT IN BOTH THEME FILES
   The brands used to be opposites -- light Cinema, brown Outtakes -- so every
   variable had to exist in both files. They are now siblings on one dark base, and
   duplicating forty identical values across two files is a silent-drift trap: change
   one, forget the other, and the two halves of the site diverge with nothing to
   catch it. Shared values are declared once in :root below; a theme file overrides
   the handful that are genuinely brand-specific. If you add a variable that both
   brands share, it belongs HERE.

   NOTE ON WIDGET STYLING
   SAIL Connect widgets render inside a shadow root (with an iframe fallback mode).
   Nothing in this file, or in either theme file, can reach their internals -- not
   with descendant selectors, not with !important. Widget theming lives server-side
   in SAIL BackOffice (Connected Site -> Site CSS, and each widget's Styling tab),
   mirrored for review under /sail-theme/. Here we style only the CONTAINER we own.
   ============================================================================= */

/* --- fonts ----------------------------------------------------------------- */
/*
   Self-hosted, not Google-hosted: the public CSP is default-src 'self' plus the SAIL
   host, so an external font origin would be blocked and every page would silently
   fall back to the system stack.

   Both are variable fonts in a single file. Archivo carries a WIDTH axis as well as
   weight, and that is the reason it is here: headings are set expanded, which is the
   voice of a marquee letter board rather than of a software product. Latin subset
   only; this is one restaurant in Minnesota. SIL OFL 1.1, see wwwroot/fonts/OFL.txt.
*/
@font-face {
    font-family: "Archivo";
    src: url("../fonts/archivo-var.woff2") format("woff2");
    font-weight: 100 900;
    font-stretch: 62% 125%;
    font-style: normal;
    font-display: swap;
}

@font-face {
    font-family: "Instrument Sans";
    src: url("../fonts/instrument-var.woff2") format("woff2");
    font-weight: 400 700;
    font-style: normal;
    font-display: swap;
}

/* --- shared palette -------------------------------------------------------- */
/*
   "House lights down." The page is the inside of an auditorium a minute before the
   film starts: a blue-black room, one warm light source. The blue-black is drawn
   from the royal blue in the Cinema Grill logo pushed almost to black -- a neutral
   #000 sits dead next to the logo's blues, and the two Outtakes logo colors are
   navy and cyan, so a blue base is the one ground both marks stand on.

   Each theme file supplies the light: gold for Cinema Grill (the film strip in the
   logo), cyan for Outtakes (the clapperboard).
*/
:root {
    --font-display: "Archivo", "Segoe UI", -apple-system, BlinkMacSystemFont, Arial, sans-serif;
    --font-body: "Instrument Sans", "Segoe UI", -apple-system, BlinkMacSystemFont, Arial, sans-serif;

    /* Headings run expanded and heavy. Both axes are variable, so this costs nothing. */
    --display-weight: 800;
    --display-stretch: 112%;
    --display-tracking: -0.005em;

    /* --- surfaces: the room --- */
    --bg: #070b16;
    --surface: #0e1428;
    --surface-raised: #171f3a;
    --line: rgba(255, 255, 255, 0.09);
    --line-strong: rgba(255, 255, 255, 0.2);
    --input-bg: rgba(255, 255, 255, 0.04);

    /* --- text --- */
    --text: #eef1f8;
    --text-soft: #b9c3da;
    --text-faint: #8895b6;

    --danger: #ff6b6b;

    /* --- header ---
       Semi-transparent over a blurred backdrop; the blur is set on .site-header. */
    --header-bg: rgba(7, 11, 22, 0.82);
    --header-text: #eef1f8;

    --alert-text: #0b1020;

    --footer-bg: #05080f;
    --footer-text: #b9c3da;
    --footer-heading: #ffffff;
    --footer-muted: #7d8aab;
    --footer-line: rgba(255, 255, 255, 0.1);
    --footer-link-hover: #ffffff;

    /* --- shape and depth ---
       Shadows on a dark page do almost nothing, so depth is carried by a hairline
       rim of light along the top edge of raised surfaces instead. */
    --radius: 12px;
    --radius-lg: 18px;
    --radius-pill: 999px;

    --shadow-sm: 0 1px 0 rgba(255, 255, 255, 0.05) inset, 0 2px 10px rgba(0, 0, 0, 0.4);
    --shadow-md: 0 1px 0 rgba(255, 255, 255, 0.06) inset, 0 16px 40px rgba(0, 0, 0, 0.5);
    --shadow-lg: 0 1px 0 rgba(255, 255, 255, 0.07) inset, 0 30px 70px rgba(0, 0, 0, 0.65);
}

/* --- reset ----------------------------------------------------------------- */

*, *::before, *::after { box-sizing: border-box; }

html {
    -webkit-text-size-adjust: 100%;
    scroll-behavior: smooth;
    /* Anchored form confirmations land under the header without this. */
    scroll-padding-top: 6rem;
    background: var(--bg);
}

body {
    margin: 0;
    font-family: var(--font-body);
    font-size: 1.0625rem;
    line-height: 1.6;
    color: var(--text);
    background: var(--bg);
    -webkit-font-smoothing: antialiased;
    text-rendering: optimizeLegibility;
}

img, svg, video { max-width: 100%; height: auto; display: block; }

a { color: var(--link); text-underline-offset: 0.18em; }
a:hover { color: var(--link-hover); }

:focus-visible {
    outline: 3px solid var(--focus);
    outline-offset: 3px;
    border-radius: 3px;
}

::selection { background: var(--accent); color: var(--accent-text); }

@media (prefers-reduced-motion: reduce) {
    html { scroll-behavior: auto; }
    *, *::before, *::after {
        animation-duration: 0.01ms !important;
        transition-duration: 0.01ms !important;
    }
}

/* --- type scale ------------------------------------------------------------ */
/*
   The display face is set expanded and heavy, and headings run a good deal larger
   than the old scale. A cinema's voice on a poster is not the same size as a
   paragraph; the previous scale topped out at 3.35rem, which read as a document
   rather than as a room you walk into.
*/
/*
   h5 and h6 are in this list because the migrated Umbraco content uses them --
   /on-screen/, /outtakes/ and /outtakes/menu/ each have one. Styling only h1-h4 left
   them at the browser default, which is BOLD AND SMALLER THAN BODY TEXT: on the
   Outtakes home page "Try our new online ordering for to go food" rendered as a tiny
   bold line that read as a styling bug. The sanitizer allows them, so they have to
   be styled here.
*/
h1, h2, h3, h4, h5, h6 {
    font-family: var(--font-display);
    font-weight: var(--display-weight);
    font-stretch: var(--display-stretch);
    line-height: 1.03;
    letter-spacing: var(--display-tracking);
    margin: 0 0 0.5em;
    text-wrap: balance;
}

h1 { font-size: clamp(2.6rem, 1.55rem + 4.4vw, 5.25rem); line-height: 0.98; }
h2 { font-size: clamp(1.85rem, 1.4rem + 1.9vw, 2.9rem); }
h3 { font-size: clamp(1.25rem, 1.1rem + 0.6vw, 1.55rem); }
h4 { font-size: 1.05rem; }
/* Below h4 the distinction is not a size step -- there is no room for one -- so it
   is carried by tracking and color instead. */
h5, h6 {
    font-size: 0.85rem;
    font-stretch: 118%;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--accent-ink);
}

p { margin: 0 0 1.15em; }

.lead {
    font-size: clamp(1.12rem, 1.03rem + 0.42vw, 1.4rem);
    line-height: 1.5;
    color: var(--text-soft);
}

.muted { color: var(--text-faint); font-size: 0.9rem; }

/*
   The eyebrow is the section's label on the board -- small, wide-tracked, in the
   brand light. It is the one place small type is allowed to be the accent color,
   which is why --accent-ink exists.
*/
.eyebrow {
    display: block;
    font-family: var(--font-display);
    font-size: 0.75rem;
    font-weight: 700;
    font-stretch: 118%;
    letter-spacing: 0.2em;
    text-transform: uppercase;
    color: var(--accent-ink);
    margin-bottom: 0.9rem;
}

/* Times, prices and dates line up in columns only with tabular figures. Both faces
   have them; this saves shipping a third family just to set a showtime. */
.tabular { font-variant-numeric: tabular-nums; }

/* --- layout primitives ----------------------------------------------------- */

.shell { width: min(1240px, 100% - 2.5rem); margin-inline: auto; }
.shell.narrow { max-width: 48rem; }

.section { padding: clamp(3rem, 6vw, 6rem) 0; }
.section-tight { padding: clamp(1.5rem, 3vw, 2.5rem) 0; }

main { min-height: 45vh; display: block; }

.link-list { list-style: none; padding: 0; margin: 0 0 1.5rem; }
.link-list li { margin-bottom: 0.5rem; }
.link-list a { font-weight: 600; }

/* Keyboard users get this as the first stop on every page; everyone else never
   sees it. It must be reachable without JavaScript, so it is a plain anchor. */
.skip-link {
    position: absolute;
    left: -9999px;
    top: 0;
    z-index: 100;
    padding: 0.75rem 1.25rem;
    background: var(--accent);
    color: var(--accent-text);
    font-weight: 700;
    text-decoration: none;
}
.skip-link:focus {
    left: 0.75rem;
    top: 0.75rem;
    border-radius: var(--radius);
}

/* --- buttons --------------------------------------------------------------- */
/*
   One filled button style, in the brand light, and one outline. There is deliberately
   no second filled color: the logo already carries red, blue and gold, and a page
   that fills buttons in two of them stops telling the visitor where to click.
*/
.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.5rem;
    padding: 0.85rem 1.75rem;
    font-family: var(--font-display);
    font-size: 0.95rem;
    font-weight: 700;
    font-stretch: 108%;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    line-height: 1.2;
    color: var(--accent-text);
    background: var(--accent);
    border: 1px solid transparent;
    border-radius: var(--radius-pill);
    box-shadow: var(--shadow-btn);
    cursor: pointer;
    text-decoration: none;
    transition: background-color 0.15s ease, transform 0.15s ease, box-shadow 0.15s ease;
}
.btn:hover {
    background: var(--accent-hover);
    color: var(--accent-text);
    transform: translateY(-2px);
    box-shadow: var(--shadow-btn-hover);
}
.btn:active { transform: none; box-shadow: var(--shadow-btn); }

.btn-ghost {
    background: transparent;
    color: var(--text);
    border-color: var(--line-strong);
    box-shadow: none;
}
.btn-ghost:hover {
    background: var(--surface-raised);
    color: var(--text);
    border-color: var(--accent);
}

.btn-lg { padding: 1rem 2.25rem; font-size: 1.02rem; }

/* --- alert banner ---------------------------------------------------------- */
/*
   Editable in the CMS and time-windowed. There is no dismiss control on purpose:
   dismissing needs JavaScript and per-visitor storage, and public pages ship neither.
   Staff turn it off by clearing the window, which is the honest control.

   It runs in the brand light with dark text, because it sits above the header and
   has to read as "news", not as chrome.
*/
.alert-banner {
    background: var(--accent);
    color: var(--alert-text);
    font-size: 0.95rem;
    font-weight: 600;
    text-align: center;
    padding: 0.6rem 0;
}
.alert-banner p { margin: 0; }
.alert-banner a { color: inherit; text-decoration: underline; }

/* --- header ---------------------------------------------------------------- */

.site-header {
    position: sticky;
    top: 0;
    z-index: 50;
    background: var(--header-bg);
    backdrop-filter: saturate(160%) blur(12px);
    -webkit-backdrop-filter: saturate(160%) blur(12px);
}

/*
   The marquee line: a warm hairline of brand light along the bottom edge of the
   header, brightest in the middle and fading at both ends. It is the only piece of
   ornament on the page and it appears exactly twice -- here and at the foot of the
   hero. Anything more (bulbs, sprocket holes, ticket perforations) turned the design
   into a costume; this is the one accessory kept on.
*/
.site-header::after {
    content: "";
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    height: 1px;
    background: var(--marquee-line);
}

.header-inner {
    display: flex;
    align-items: center;
    gap: clamp(0.75rem, 2vw, 2rem);
    padding: 0.75rem 0;
}

.brand {
    display: flex;
    align-items: center;
    gap: 0.85rem;
    text-decoration: none;
    color: var(--header-text);
    margin-right: auto;
    flex: 0 0 auto;
}
/*
   The badge, on transparency so the dark page shows through it. Height is fixed and
   width follows -- the two logos have different aspect ratios and pinning both would
   squash one. It reads as an emblem at this size, which is all it is asked to do;
   the name beside it is what a visitor actually reads.
*/
.brand-logo {
    height: 52px;
    width: auto;
    flex: 0 0 auto;
}

.brand-words { display: block; line-height: 1.1; }

.brand-name {
    display: block;
    font-family: var(--font-display);
    font-weight: 800;
    font-stretch: 112%;
    font-size: clamp(1.05rem, 0.95rem + 0.35vw, 1.3rem);
    letter-spacing: -0.005em;
    color: var(--header-text);
}

.brand-sub {
    display: block;
    font-family: var(--font-display);
    font-size: 0.62rem;
    font-weight: 700;
    font-stretch: 118%;
    letter-spacing: 0.18em;
    text-transform: uppercase;
    color: var(--accent-ink);
    margin-top: 0.25rem;
}

.site-nav { display: flex; align-items: center; gap: clamp(0.9rem, 1.6vw, 1.6rem); }

.site-nav a {
    position: relative;
    text-decoration: none;
    font-family: var(--font-display);
    font-weight: 600;
    font-stretch: 104%;
    font-size: 0.92rem;
    color: var(--header-text);
    padding: 0.35rem 0;
    white-space: nowrap;
    transition: color 0.15s ease;
}
/* The underline is a pseudo-element rather than a border so it can animate width
   without shifting the row height. */
.site-nav a::after {
    content: "";
    position: absolute;
    left: 0;
    right: 100%;
    bottom: 0;
    height: 2px;
    background: var(--accent);
    transition: right 0.18s ease;
}
.site-nav a:hover::after,
.site-nav a.is-current::after { right: 0; }
.site-nav a:hover { color: var(--accent-ink); }
.site-nav a.is-current { color: var(--accent-ink); }

.header-cta { display: flex; align-items: center; gap: 0.75rem; flex: 0 0 auto; }

.brand-switch {
    display: inline-block;
    padding: 0.5rem 1.05rem;
    border: 1px solid var(--line-strong);
    border-radius: var(--radius-pill);
    text-decoration: none;
    font-family: var(--font-display);
    font-size: 0.82rem;
    font-weight: 600;
    font-stretch: 104%;
    color: var(--header-text);
    white-space: nowrap;
    transition: border-color 0.15s ease, background-color 0.15s ease, color 0.15s ease;
}
.brand-switch:hover {
    color: var(--accent-ink);
    border-color: var(--accent);
    background: var(--surface-raised);
}

/* The Order Online launcher lives in the header on every page and is the primary
   conversion action, so it stays in the bar at all widths -- never inside the
   mobile drawer. Its own min-height is passed as 0 from SiteHeader. */
.header-order { display: flex; align-items: center; }

/* --- mobile navigation ----------------------------------------------------- */
/*
   Two navigations in the markup, one visible at a time. The <details> disclosure is
   the mobile one; the plain <nav> is the desktop one. They are NOT the same element
   toggled by a media query, because a closed <details> hides its own children in a
   way host CSS cannot override in every browser we have to support -- ::details-content
   is too new to bet the main navigation on. Whichever is display:none is also out of
   the accessibility tree, so screen readers only ever see one.

   No JavaScript is involved. Public pages ship none -- see App.razor.
*/
.nav-desktop { display: flex; }
.nav-mobile { display: none; position: relative; }

.nav-mobile > summary {
    list-style: none;
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.55rem 0.95rem;
    border: 1px solid var(--line-strong);
    border-radius: var(--radius-pill);
    font-family: var(--font-display);
    font-size: 0.82rem;
    font-weight: 600;
    color: var(--header-text);
    cursor: pointer;
    user-select: none;
}
.nav-mobile > summary::-webkit-details-marker { display: none; }

.nav-burger {
    display: block;
    width: 1.1rem;
    height: 2px;
    background: currentColor;
    position: relative;
}
.nav-burger::before,
.nav-burger::after {
    content: "";
    position: absolute;
    left: 0;
    width: 100%;
    height: 2px;
    background: currentColor;
}
.nav-burger::before { top: -0.34rem; }
.nav-burger::after { top: 0.34rem; }

.nav-mobile[open] > summary { border-color: var(--accent); color: var(--accent-ink); }

.nav-drawer {
    position: absolute;
    right: 0;
    top: calc(100% + 0.6rem);
    z-index: 60;
    min-width: min(17rem, 78vw);
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
    padding: 0.6rem;
    background: var(--surface-raised);
    border: 1px solid var(--line);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-lg);
}
.nav-drawer a {
    display: block;
    padding: 0.65rem 0.8rem;
    border-radius: var(--radius);
    text-decoration: none;
    font-family: var(--font-display);
    font-weight: 600;
    color: var(--text);
}
.nav-drawer a:hover { background: rgba(255, 255, 255, 0.06); color: var(--accent-ink); }
.nav-drawer a.is-current { color: var(--accent-ink); }
.nav-drawer .brand-switch {
    margin-top: 0.5rem;
    text-align: center;
    padding: 0.65rem 0.8rem;
}

/*
   1200px, not the 980px that fits Cinema Grill.

   The two brands do not have the same number of nav items -- Outtakes has seven to
   Cinema Grill's six -- and the header is one row of nowrap text, so it cannot
   shrink; it can only overflow. The breakpoint has to clear the WIDER navigation or
   one brand blows the layout out sideways at widths the other survives. Measured,
   not guessed: /outtakes/ pushes .header-cta (the Order Online launcher) past the
   viewport at 1160px and clears it at 1200px.

   It follows that this is nav-item-count sensitive. If staff add an eighth page to
   the Outtakes navigation, re-measure -- tools/find-overflow probing is the only way
   to see it, because the symptom is a horizontal scrollbar at one range of widths.
*/
@media (max-width: 1200px) {
    .nav-desktop { display: none; }
    .nav-mobile { display: block; }
    .header-cta { gap: 0.5rem; }
    /* The cross-brand link moves into the drawer at this width -- SiteHeader renders
       one in each place, so hide the bar copy rather than adding a class for it. */
    .header-cta > .brand-switch { display: none; }
}

/* On a phone the launcher and the menu button need the row more than the wordmark
   does, and the badge alone still identifies the page. */
@media (max-width: 560px) {
    .brand-logo { height: 46px; }
    .brand-words { display: none; }
}

/* --- hero ------------------------------------------------------------------ */

.hero {
    position: relative;
    isolation: isolate;
    overflow: hidden;
    background: var(--hero-bg);
}

/* The second and last appearance of the marquee line, closing the hero. */
.hero::after {
    content: "";
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    height: 1px;
    background: var(--marquee-line);
    z-index: 3;
}

.hero-inner {
    position: relative;
    z-index: 2;
    padding-block: clamp(2.75rem, 7vw, 5.5rem);
}
/*
   The measure is capped on the CHILDREN, not on .hero-inner itself. .hero-inner also
   carries .shell, which centers with margin-inline:auto -- so a max-width here shrank
   the whole box and re-centered it, putting the hero heading a couple of hundred pixels
   to the right of the navigation and every block below it.
*/
.hero-inner > * { max-width: 20ch; }
.hero-inner > .hero-sub { max-width: 42ch; }
.hero-inner h1 { margin-bottom: 0.3em; }

.hero-sub {
    font-size: clamp(1.08rem, 1rem + 0.55vw, 1.42rem);
    line-height: 1.45;
    margin: 0;
    color: var(--hero-sub-text);
}

/*
   A wash of brand light thrown from the top-left corner, as if from a projector
   behind the visitor. It is what stops the hero reading as a flat color band, and
   it is the reason the hero needs no photograph to look finished -- which matters,
   because most of the legacy image library is 2019 event flyers.
*/
.hero-plain::before {
    content: "";
    position: absolute;
    inset: 0;
    z-index: 1;
    background: var(--hero-wash);
    pointer-events: none;
}

/* Pages with a hero image: the image is a decorative background, so it carries
   empty alt and aria-hidden in the markup. fetchpriority=high is set there too --
   this is the LCP element on nearly every page. */
.hero-image .hero-bg {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    z-index: 0;
}
.hero-image::before {
    content: "";
    position: absolute;
    inset: 0;
    z-index: 1;
    background: var(--hero-scrim);
}

/*
   --hero-scrim is ANGLED (100deg), which is right on a wide screen: the text sits in the
   dark left and the photograph survives on the right. On a phone the hero text spans the
   full width, so the pale end of that gradient ends up directly behind the subheading --
   --text-soft over a mid-bright photo, which is where it stops being readable.

   Below 760px, go near-vertical and uniformly darker. The photo drops to texture, which is
   the correct trade: it is a decorative background and the words are the content.
*/
@media (max-width: 760px) {
    .hero-image::before {
        background: linear-gradient(180deg,
            rgba(7, 11, 22, 0.88) 0%,
            rgba(7, 11, 22, 0.8) 60%,
            rgba(7, 11, 22, 0.74) 100%);
    }
}

/* Pages with neither a hero image nor a hero heading -- the title still has to be
   the only h1 on the page. */
.page-head { padding-block: clamp(2.75rem, 6vw, 4.5rem) 0; }
.page-head h1 { margin-bottom: 0; }
.page-head::after {
    content: "";
    display: block;
    width: 4rem;
    height: 3px;
    margin-top: 1.5rem;
    border-radius: 2px;
    background: var(--accent);
}

/* --- content blocks -------------------------------------------------------- */

.page-body { padding-block: clamp(2.5rem, 5.5vw, 4.5rem); }

.block + .block { margin-top: clamp(2.5rem, 5vw, 4.5rem); }

/* Utility classes staff can type into a block's "Layout options" field. Keep this
   list, the help text in the page editor and these rules in step -- an undocumented
   class is one nobody uses, and an unimplemented one looks like a bug. */
.block.narrow { max-width: 48rem; margin-inline: auto; }
.block.center { text-align: center; }
.block.center .btn { margin-inline: auto; }
.block.tight + .block { margin-top: 1.5rem; }
.block.tint {
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--radius-lg);
    padding: clamp(1.75rem, 4vw, 3rem);
    box-shadow: var(--shadow-sm);
}
.block.tint > :last-child { margin-bottom: 0; }

/* --- rich text ------------------------------------------------------------- */
/*
   Everything inside .rte came out of the sanitizer, so the tag set is known and
   small: headings, p, lists, links, tables, blockquote, hr, and inline emphasis.
   text-align survives as an inline style -- the legacy Umbraco content uses it
   heavily and losing it would visibly regress the migration.
*/
.rte > :first-child { margin-top: 0; }
.rte > :last-child { margin-bottom: 0; }

/*
   Cap the measure on prose only. The shell is 1240px wide because widgets, package
   cards and the seven-day schedule need it; a paragraph at that width is well over
   150 characters a line, roughly twice what anyone reads comfortably. Scoped to the
   rich-text BLOCK so it does not also squeeze the copy inside package cards, form
   intros or the footer, which are already narrow.

   Staff can override per block with the "narrow" / "center" layout options.
*/
.block-richtext > .rte { max-width: 66ch; }
.block-richtext.center > .rte { margin-inline: auto; }

.rte h2 { margin-top: 1.6em; }
.rte h3 { margin-top: 1.5em; }
.rte h4 { margin-top: 1.4em; color: var(--text-soft); }
.rte h5, .rte h6 { margin-top: 2em; margin-bottom: 0.9em; }

.rte ul, .rte ol { margin: 0 0 1.15em; padding-left: 1.35em; }
.rte li { margin-bottom: 0.4em; }
.rte li::marker { color: var(--accent-ink); }

.rte a { font-weight: 600; }

.rte blockquote {
    margin: 1.75em 0;
    padding: 0.25rem 0 0.25rem 1.35rem;
    border-left: 3px solid var(--accent);
    color: var(--text-soft);
    font-size: 1.1rem;
}

.rte hr {
    border: 0;
    height: 1px;
    background: var(--line);
    margin: 2.5em 0;
}

/* Legacy tables are wider than a phone. Let them scroll inside their own box
   rather than pushing the whole document sideways. */
.rte table {
    width: 100%;
    border-collapse: collapse;
    margin: 0 0 1.5em;
    font-size: 0.95rem;
    display: block;
    overflow-x: auto;
}
.rte th, .rte td {
    padding: 0.7rem 0.9rem;
    border-bottom: 1px solid var(--line);
    text-align: left;
    vertical-align: top;
}
.rte th {
    font-family: var(--font-display);
    font-weight: 700;
    font-stretch: 108%;
    font-size: 0.85rem;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--text-soft);
}

/* --- image block ----------------------------------------------------------- */

.img-block { margin: 0; }
.img-block img { border-radius: var(--radius-lg); box-shadow: var(--shadow-md); }
.img-block figcaption {
    margin-top: 0.8rem;
    font-size: 0.88rem;
    color: var(--text-faint);
}

.img-full img { width: 100%; }
.img-center { text-align: center; }
.img-center img { margin-inline: auto; }

/* Float only where there is room to wrap text around it. Below that the image
   goes full width, which is what a phone wants anyway. */
@media (min-width: 720px) {
    .img-left { float: left; margin: 0.4rem 2rem 1.25rem 0; max-width: 45%; }
    .img-right { float: right; margin: 0.4rem 0 1.25rem 2rem; max-width: 45%; }
    .block::after { content: ""; display: table; clear: both; }
}

/* --- SAIL widget containers ------------------------------------------------- */
/*
   These three rules are the ENTIRE surface host CSS is allowed to touch on the
   widget element itself. Custom elements default to display:inline, which is wrong
   for every widget; the launcher wants inline-block so it can sit in a flex row.
   If the Order Online button ever renders full-width, this rule went missing.
*/
sail-widget { display: block; }
sail-widget[type="oo-launcher"] { display: inline-block; }

/* Reserve space. Widget failure is silent -- the element simply never upgrades --
   so without this a SAIL outage collapses the page instead of leaving a gap. */
.sail-widget-frame { min-height: 220px; }

/*
   Widgets sit DIRECTLY on the dark page. There is no panel, no background and no
   color flip here on purpose -- the design is immersive, and the widgets are themed
   DARK in SAIL BackOffice (mirrored under /sail-theme/) so showtimes, the menu and
   gift cards read as part of the room rather than as an embed on a screen.

   The lit near-white panel that used to live here (".the screen") was removed by
   request. The consequence it used to paper over is now real: an UNTHEMED widget
   hard-codes white cards and inputs inside its shadow root, and on this page that
   renders as white rectangles floating on a dark room. If a widget looks like that,
   the fix is its BackOffice Styling tab, not host CSS -- nothing in this file can
   reach inside the shadow root.
*/

/* The launcher block is a single button in flow; never reserve panel height for it. */
.block-widget:has(sail-widget[type="oo-launcher"]) .sail-widget-frame { min-height: 0; }

/*
   Widgets do not all want the same width, and we cannot measure them -- their content
   is behind a shadow boundary. What we DO know is the widget's type, which is on the
   element as an attribute.

   The gift-card lookup is one short form; left at the full 1240px shell it sat
   marooned at the edge of a very wide row. The ticket and menu grids genuinely use
   the width.
*/
.block-widget:has(sail-widget[type="gift-card-lookup"]) {
    max-width: 38rem;
    margin-inline: auto;
}

.widget-fallback {
    padding: 1.25rem;
    border: 1px dashed var(--line);
    border-radius: var(--radius);
    color: var(--text-faint);
    margin: 0;
}

/* --- weekly schedule ------------------------------------------------------- */

/*
   Seven equal columns once there is room for them, and only then. auto-fit alone
   gave six columns at 1440px and wrapped Saturday onto a row of its own, which
   reads as a bug -- a week has a shape and people expect to see it.
*/
.schedule-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(9.5rem, 1fr));
    gap: 0.75rem;
}
@media (min-width: 1000px) {
    .schedule-grid { grid-template-columns: repeat(7, 1fr); }
}

.schedule-day {
    display: flex;
    flex-direction: column;
    padding: 1.15rem 1.05rem 1.35rem;
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    box-shadow: var(--shadow-sm);
}
/* A day with nothing on it is information too, but it should recede rather than
   sit in the row looking like a card that failed to load. */
.schedule-day.is-empty {
    background: transparent;
    border-style: dashed;
    box-shadow: none;
    color: var(--text-faint);
}

.schedule-dayname {
    font-family: var(--font-display);
    font-size: 0.7rem;
    font-weight: 700;
    font-stretch: 118%;
    letter-spacing: 0.18em;
    text-transform: uppercase;
    color: var(--text-faint);
    padding-bottom: 0.7rem;
    margin: 0 0 0.85rem;
    border-bottom: 1px solid var(--line);
}
.schedule-day:not(.is-empty) .schedule-dayname { color: var(--accent-ink); }

.schedule-item + .schedule-item {
    margin-top: 0.9rem;
    padding-top: 0.9rem;
    border-top: 1px dashed var(--line);
}

.schedule-name {
    font-family: var(--font-display);
    font-weight: 700;
    font-stretch: 104%;
    font-size: 1.05rem;
    line-height: 1.15;
    margin: 0 0 0.2rem;
}
.schedule-time {
    margin: 0;
    font-weight: 600;
    font-size: 0.9rem;
    font-variant-numeric: tabular-nums;
    color: var(--text-soft);
}
.schedule-desc { margin: 0.5rem 0 0; font-size: 0.88rem; color: var(--text-faint); line-height: 1.45; }
.schedule-none { margin: 0; }

.schedule-list { margin: 0; }
.schedule-list dt {
    font-family: var(--font-display);
    font-size: 0.7rem;
    font-weight: 700;
    font-stretch: 118%;
    letter-spacing: 0.18em;
    text-transform: uppercase;
    color: var(--accent-ink);
    margin-top: 1.5rem;
}
.schedule-list dd {
    margin: 0.35rem 0 0;
    padding-bottom: 1rem;
    border-bottom: 1px solid var(--line);
}
.schedule-list dd .schedule-name { display: inline; margin-right: 0.6rem; }
.schedule-list dd .schedule-time { display: inline; }
.schedule-list dd .schedule-desc { display: block; }

/* --- party / group packages ------------------------------------------------ */

.packages {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(20rem, 100%), 1fr));
    gap: 1.25rem;
}

.package {
    display: flex;
    flex-direction: column;
    padding: clamp(1.5rem, 3vw, 2.25rem);
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-sm);
}

.package-name { margin: 0 0 0.7rem; }

.package-price {
    display: flex;
    align-items: baseline;
    gap: 0.4rem;
    margin: 0 0 0.5rem;
}
.package-amount {
    font-family: var(--font-display);
    font-weight: 800;
    font-stretch: 112%;
    font-size: clamp(2.1rem, 1.7rem + 1.4vw, 2.9rem);
    line-height: 1;
    color: var(--accent-ink);
    letter-spacing: -0.02em;
    font-variant-numeric: tabular-nums;
}
.package-unit { font-size: 0.9rem; color: var(--text-faint); }

.package-guests {
    margin: 0 0 1.1rem;
    font-family: var(--font-display);
    font-size: 0.75rem;
    font-weight: 700;
    font-stretch: 112%;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--text-faint);
}

.package-summary { color: var(--text-soft); }

/* The includes list is CMS HTML, so style the tags the sanitizer allows rather
   than assuming a class. Custom markers read as a feature list instead of prose. */
.package-includes { margin-bottom: 1rem; }
.package-includes ul { list-style: none; padding: 0; margin: 0; }
.package-includes li {
    position: relative;
    padding-left: 1.6rem;
    margin-bottom: 0.5rem;
}
.package-includes li::before {
    content: "";
    position: absolute;
    left: 0;
    top: 0.5em;
    width: 0.7rem;
    height: 0.4rem;
    border-left: 2px solid var(--accent);
    border-bottom: 2px solid var(--accent);
    transform: rotate(-45deg);
}

.package-fineprint {
    margin: auto 0 0;
    padding-top: 1.1rem;
    font-size: 0.82rem;
    color: var(--text-faint);
}

/* --- forms ----------------------------------------------------------------- */

label {
    display: block;
    font-family: var(--font-display);
    font-weight: 600;
    font-size: 0.88rem;
    letter-spacing: 0.02em;
    margin-bottom: 0.4rem;
    color: var(--text-soft);
}

/*
   Selected by exclusion, not by listing the types we want.

   Blazor's <InputText> renders a bare <input> with NO type attribute at all, so a
   selector like input[type="text"] does not match it. That left the fields bound
   with InputText -- name, subject, organization -- at the browser's default ~180px
   while the ones that happen to carry type="email" or type="tel" went full width,
   on the same row. It looked like a broken grid and was a missing selector.
*/
input:not([type="checkbox"]):not([type="radio"]):not([type="hidden"]):not([type="submit"]):not([type="button"]):not([type="reset"]):not([type="file"]):not([type="image"]),
select, textarea {
    width: 100%;
    padding: 0.75rem 0.9rem;
    font: inherit;
    font-size: 1rem;
    color: var(--text);
    background: var(--input-bg);
    border: 1px solid var(--line-strong);
    border-radius: var(--radius);
    transition: border-color 0.15s ease, box-shadow 0.15s ease, background-color 0.15s ease;
}
input:focus, select:focus, textarea:focus {
    outline: none;
    border-color: var(--accent);
    background: rgba(255, 255, 255, 0.06);
    box-shadow: 0 0 0 3px var(--accent-glow);
}
input::placeholder, textarea::placeholder { color: var(--text-faint); }

/*
   The native date and time pickers draw a dark glyph, which vanishes on a dark
   field. Both public brands are dark, so this applies to both -- but it is scoped to
   body.public rather than left unconditional, because the admin is a light UI on the
   same base.css and inverting there would paint a white glyph on a white field.
   App.razor sets that class.
*/
body.public input[type="date"]::-webkit-calendar-picker-indicator,
body.public input[type="time"]::-webkit-calendar-picker-indicator {
    filter: invert(1) opacity(0.65);
}

textarea { min-height: 8.5rem; resize: vertical; }

.validation-message { display: block; margin-top: 0.4rem; color: var(--danger); font-size: 0.88rem; }
.invalid { border-color: var(--danger) !important; }

/* Honeypot: must be reachable by nothing a human uses, but NOT display:none --
   some bots skip hidden fields. Off-screen positioning catches more of them. */
.hp-field {
    position: absolute;
    left: -9999px;
    width: 1px;
    height: 1px;
    overflow: hidden;
}

/* Same argument as the prose measure: a text field 1200px wide looks like a mistake,
   and a three-line message box that wide is worse. */
.form-block {
    max-width: 54rem;
    padding: clamp(1.75rem, 4vw, 2.75rem);
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-sm);
}
.form-intro { margin-bottom: 1.75rem; }
.form-intro > :last-child { margin-bottom: 0; }

.field { margin-bottom: 1.2rem; }

/* Rows collapse to one column without a media query -- the min() in the flex
   basis does it, so the breakpoint follows the container rather than the viewport. */
.field-row { display: flex; flex-wrap: wrap; gap: 0 1.1rem; }
.field-row > .field { flex: 1 1 min(18rem, 100%); }
.field-row > .field-narrow { flex: 0 1 8rem; }

.form-thanks {
    padding: clamp(1.5rem, 3vw, 2.25rem);
    border: 1px solid var(--line);
    border-left: 4px solid var(--accent);
    border-radius: var(--radius-lg);
    background: var(--surface-raised);
}
.form-thanks h2 { margin-top: 0; }
.form-thanks p:last-child { margin-bottom: 0; }

/* "Please send that again" -- a submission that could not be trusted but probably
   came from a person. Not a validation error, so it does not use --danger. */
.form-notice {
    padding: 0.9rem 1.15rem;
    margin-bottom: 1.75rem;
    border: 1px solid var(--line);
    border-left: 4px solid var(--accent);
    border-radius: var(--radius);
    background: var(--surface-raised);
}

.form-alt {
    margin: 1.75rem 0 0;
    padding-top: 1.25rem;
    border-top: 1px solid var(--line);
    color: var(--text-faint);
    font-size: 0.92rem;
}

/* --- footer ---------------------------------------------------------------- */

/*
   No margin-top. .page-body already pads the bottom of every page, and adding a
   footer margin on top of it stacked the two into roughly 230px of empty page above
   the footer rule. The footer's own top padding is the separation.
*/
.site-footer {
    padding: clamp(3rem, 6vw, 4.5rem) 0 1.75rem;
    background: var(--footer-bg);
    color: var(--footer-text);
    font-size: 0.95rem;
    border-top: 1px solid var(--footer-line);
}

.footer-inner {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(15rem, 100%), 1fr));
    gap: clamp(1.75rem, 4vw, 3rem);
}

.footer-title {
    font-family: var(--font-display);
    font-weight: 700;
    font-stretch: 112%;
    font-size: 0.8rem;
    letter-spacing: 0.16em;
    text-transform: uppercase;
    margin-bottom: 1rem;
    color: var(--footer-heading);
}

.site-footer p { margin: 0 0 0.9rem; }
.site-footer ul { list-style: none; padding: 0; margin: 0; }
.site-footer li { margin-bottom: 0.5rem; }
.site-footer a { color: inherit; text-decoration: none; }
.site-footer a:hover { color: var(--footer-link-hover); text-decoration: underline; }

.footer-hours { margin-top: 1rem; font-size: 0.9rem; color: var(--footer-muted); }
.footer-hours > :last-child { margin-bottom: 0; }

.footer-social { display: flex; flex-wrap: wrap; gap: 0.5rem; margin-top: 1.1rem !important; }
.footer-social li { margin: 0; }
.footer-social a {
    display: inline-block;
    padding: 0.4rem 0.85rem;
    border: 1px solid var(--footer-line);
    border-radius: var(--radius-pill);
    font-size: 0.8rem;
    font-weight: 600;
}
.footer-social a:hover { text-decoration: none; border-color: var(--accent); color: var(--footer-link-hover); }

.footer-legal {
    margin-top: clamp(2rem, 5vw, 3rem);
    padding-top: 1.35rem;
    border-top: 1px solid var(--footer-line);
    font-size: 0.85rem;
    color: var(--footer-muted);
}
.footer-legal p { margin: 0; }

/* --- print ----------------------------------------------------------------- */
/*
   Menus, party packages and directions do get printed. Drop the chrome and the
   widgets -- a widget prints as a blank rectangle because its shadow content is
   not in the print document. The screen is dark on a monitor and must be black on
   white on paper, so the palette is restated rather than inherited.
*/
@media print {
    .site-header, .site-footer, .alert-banner, .skip-link,
    .sail-widget-frame, .form-block { display: none !important; }

    html, body { background: #fff !important; color: #000 !important; }
    body { font-size: 11pt; }

    .hero, .hero-plain, .block-widget { background: none !important; box-shadow: none !important; }
    .hero-image .hero-bg, .hero-image::before, .hero::after { display: none !important; }
    h1, h2, h3, h4, .hero-sub, .lead, .rte, .schedule-name, .package-amount { color: #000 !important; }
    .muted, .schedule-desc, .package-fineprint, .package-unit { color: #444 !important; }
    .package, .schedule-day, .block.tint { border: 1px solid #999 !important; box-shadow: none !important; }
    a[href^="http"]::after { content: " (" attr(href) ")"; font-size: 9pt; }
}
