/*
 * Butte College — Resource Hub Interaction Surface
 *
 * A reusable style pattern for embedding interactive surfaces (wizards,
 * routing tools, lookup widgets, mini-forms) inside the existing Resource
 * Hub accordion rows on the public website.
 *
 * Use by wrapping the interactive content in:
 *
 *   <section class="bc-hub-surface" aria-label="...">
 *     <header class="bc-hub-surface__header">...</header>
 *     <div class="bc-hub-surface__body">...</div>
 *     <footer class="bc-hub-surface__footer">...</footer>
 *   </section>
 *
 * The surface is intentionally self-contained: every selector is scoped
 * under .bc-hub-surface so it cannot leak into the rest of the Cascade
 * page. Drop a sibling stylesheet that defines widget-specific layout
 * (e.g., counseling-router.css) on top of this base.
 *
 * ----- Visual envelope policy -----
 *
 * The default surface is FLUSH: no outer margin, no border, no
 * border-radius. Drop it inside a hub-row content area and it fills the
 * available width edge-to-edge. The widget body keeps its own internal
 * padding so content does not collide with the row edges.
 *
 * Why flush by default?
 *   - The hub row already provides chrome (cream background, gold top
 *     bar, accordion toggle). A bordered surface inside a bordered row
 *     produces nested-box visual noise that is hard to align.
 *   - Standardizing on "surface IS the row content" means new widgets do
 *     not have to redo border math on every page.
 *
 * If the host hub row has its own horizontal padding, add this single
 * rule to the host site CSS so surfaces bleed to the row edges:
 *
 *     .hub-row__content:has(> .bc-hub-surface) { padding: 0; }
 *
 * (Replace .hub-row__content with whatever class wraps the accordion
 * body in your Cascade hub format.)
 *
 * For standalone use (a surface that does NOT live inside a hub — e.g.,
 * a one-off page widget) add the .bc-hub-surface--bordered modifier to
 * restore margin / border / rounded corners.
 *
 * WCAG 2.2 notes:
 *   - Body text uses #1a1a1a on #ffffff (~17:1) — AAA
 *   - Muted text uses #4a4a4a on #ffffff (~9.7:1) — AAA
 *   - Link/accent uses #8a6700 on #ffffff (~5.6:1) — AA
 *   - Gold fills use #1a1a1a on #FFC629 (~12:1) — AAA on the fill
 *   - All interactive elements have a visible focus indicator
 *   - Touch targets are at least 44x44 CSS px (AAA)
 *   - prefers-reduced-motion respected
 *   - prefers-color-scheme: not yet themed (Butte public site is light only)
 *   - Reflow tested at 320px viewport width
 *   - Color is never the sole signal: status uses icon + text
 */

.bc-hub-surface {
    /* Palette — override at this scope only to retheme an instance. */
    --bc-hub-bg: #ffffff;
    --bc-hub-bg-alt: #f7f4ec;
    --bc-hub-ink: #1a1a1a;
    --bc-hub-muted: #4a4a4a;
    --bc-hub-border: #c8c0a8;
    --bc-hub-border-strong: #8a7d56;
    --bc-hub-accent-text: #8a6700;
    --bc-hub-accent-strong: #5e4500;
    --bc-hub-fill-gold: #FFC629;
    --bc-hub-fill-gold-hover: #e6b020;
    --bc-hub-fill-gold-on: #1a1a1a;
    --bc-hub-fill-dark: #1a3d2e;
    --bc-hub-fill-dark-hover: #102b1f;
    --bc-hub-fill-dark-on: #ffffff;
    --bc-hub-error-text: #8a1a1a;
    --bc-hub-success-text: #1a5d2e;

    --bc-hub-radius: 6px;
    --bc-hub-radius-sm: 3px;
    --bc-hub-gutter: clamp(0.75rem, 0.5rem + 1vw, 1.25rem);
    --bc-hub-stack: 1rem;

    background: var(--bc-hub-bg);
    color: var(--bc-hub-ink);
    /* Flush by default — the surface fills its host row edge-to-edge. */
    border: 0;
    border-radius: 0;
    margin: 0;
    padding: var(--bc-hub-gutter);
    font-family: system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
    font-size: 1.4rem;
    line-height: 1.55;
    /* Reset any inherited list bullets / hub spacing the host page might apply */
    text-align: left;
    /* Display block so the section never inherits inline-flex from a
       weirdly-styled parent. */
    display: block;
}

/* Standalone use: outside a Resource Hub. Adds back the chrome the flush
   default removes. Apply by adding .bc-hub-surface--bordered. */
.bc-hub-surface--bordered {
    border: 1px solid var(--bc-hub-border);
    border-radius: var(--bc-hub-radius);
    margin: 0.75rem 0;
}

/* ----- Bleed-to-edge embed pattern -----
 *
 * When a .bc-hub-surface is the direct child of any container (Cascade's
 * hub-row content wrapper, the demo's .hub-row__content, etc.), strip
 * that container's horizontal padding so the surface fills the row
 * edge-to-edge. Vertical padding is intentionally preserved so the
 * surrounding hub still has breathing room above and below.
 *
 * Why this works without !important:
 *   :has() inherits the specificity of what's inside it, so
 *   :has(> .bc-hub-surface) has specificity (0,1,0) — the same as
 *   any single-class selector like .hub-row__content. Cascade-order
 *   wins on a tie, and this file loads after the host page CSS, so
 *   our rule wins cleanly without a hammer.
 *
 * Opt-out for one row only:
 *   Put .bc-hub-surface--no-bleed on the surface OR wrap the surface
 *   in a plain <div> so it's no longer a direct child of the hub
 *   wrapper. Either escape hatch is documentable and reversible —
 *   no team member ever needs to fight an !important.
 *
 * Accessibility (verified against project policy WCAG 2.2 AA):
 *   - No new focusable elements introduced; tab order unchanged.
 *   - Visible focus indicators on widget controls are inside the
 *     widget, not on the parent — bleed doesn't touch them.
 *   - Color contrast unchanged (no colors set on the parent).
 *   - Reflow at 320 px still works; the widget's own grid + flex
 *     rules handle narrow viewports independently.
 *   - prefers-reduced-motion: no motion added by this rule.
 *   - High-contrast / forced-colors mode: padding is style-only,
 *     unaffected by user color overrides.
 */
:has(> .bc-hub-surface:not(.bc-hub-surface--no-bleed)) {
    padding-left: 0;
    padding-right: 0;
}

/* Opt-out modifier on the surface itself — useful when an editor
   explicitly wants the host row's normal horizontal padding back. The
   :not() inside the :has() above means this modifier prevents the
   bleed rule from matching the parent in the first place. */
.bc-hub-surface--no-bleed { /* marker only; the bleed rule handles this */ }

.bc-hub-surface *,
.bc-hub-surface *::before,
.bc-hub-surface *::after {
    box-sizing: border-box;
}

/* ----- Surface regions ----- */

.bc-hub-surface__header {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem 1rem;
    align-items: baseline;
    justify-content: space-between;
    padding-bottom: 0.75rem;
    margin-bottom: var(--bc-hub-stack);
    border-bottom: 2px solid var(--bc-hub-fill-gold);
}

.bc-hub-surface__title {
    /* Widget title — sized to roughly match Butte's page-section heading
       so the embedded widget reads as part of the host page hierarchy
       rather than a small embedded card. */
    font-size: 2rem;
    font-weight: 700;
    margin: 0;
    color: var(--bc-hub-ink);
    line-height: 1.2;
}

.bc-hub-surface__subtitle {
    font-size: 1.4rem;
    font-weight: 500;
    margin: 0;
    color: var(--bc-hub-muted);
}

.bc-hub-surface__body {
    display: block;
}

.bc-hub-surface__body > * + * {
    margin-top: var(--bc-hub-stack);
}

.bc-hub-surface__footer {
    margin-top: calc(var(--bc-hub-stack) * 1.25);
    padding-top: 0.75rem;
    border-top: 1px solid var(--bc-hub-border);
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    align-items: center;
    justify-content: flex-end;
}

/* ----- Typography -----
 *
 * Minimum body-text size policy: 1rem.
 *
 * The host site's hub-row body text (e.g., "Counseling and Career
 * Services" in the row metadata) renders at the user's default rem
 * size. To keep the embedded widget readable next to that baseline,
 * NOTHING in this stylesheet should drop below 1rem font-size. Visual
 * hierarchy is carried by font-weight, color, and uppercase/letter-
 * spacing — not by smaller text.
 *
 * Exception: print artifact (counseling-router-print.css) uses point
 * sizes intentionally; that file targets paper, not screens. The
 * print stylesheet only applies inside @media print and its base
 * rules are scoped to the .bc-counseling-router__print-only subtree
 * which is sr-only on screen.
 *
 * WCAG 1.4.4 (Resize Text) requires text resize to 200% without
 * loss — using rem throughout ensures that. Browser/user zoom and
 * the system font-size preference both flow through.
 */

.bc-hub-surface h2,
.bc-hub-surface h3,
.bc-hub-surface h4 {
    color: var(--bc-hub-ink);
    line-height: 1.25;
    margin: 0 0 0.5rem;
}

.bc-hub-surface h2 { font-size: 1.7rem;   font-weight: 700; }
.bc-hub-surface h3 { font-size: 1.5rem;  font-weight: 600; }
.bc-hub-surface h4 { font-size: 1.4rem;  font-weight: 600; }

.bc-hub-surface p { margin: 0 0 0.5rem; }
.bc-hub-surface p:last-child { margin-bottom: 0; }

/* Plain-link defaults inside the surface. :where() drops the element
   selector's contribution to 0 so .bc-hub-surface__btn (specificity
   0,1,0) can win when the same element is both a link AND a styled
   button. Without this wrap, "BOOK AN APPOINTMENT" (an <a> with the
   dark-button modifier) inherits this gold link color over the dark
   button's white, producing a WCAG-failing gold-on-dark-green. */
.bc-hub-surface :where(a) {
    color: var(--bc-hub-accent-text);
    text-decoration: underline;
    text-underline-offset: 0.18em;
    text-decoration-thickness: 1px;
}

.bc-hub-surface :where(a):hover {
    color: var(--bc-hub-accent-strong);
    text-decoration-thickness: 2px;
}

.bc-hub-surface :where(a):focus-visible {
    outline: 3px solid var(--bc-hub-accent-strong);
    outline-offset: 2px;
    border-radius: var(--bc-hub-radius-sm);
}

/* Broad list defaults are wrapped in :where() so a widget grid (e.g.
   .bc-counseling-router__eligibility-grid) with single-class specificity
   can override them via cascade order without an !important. */
.bc-hub-surface :where(ul, ol) {
    margin: 0.25rem 0 0.5rem 1.25rem;
    padding: 0;
}

.bc-hub-surface :where(li + li) { margin-top: 0.25rem; }

/* ----- Step / progress indicator ----- */

.bc-hub-surface__steps {
    list-style: none;
    margin: 0 0 var(--bc-hub-stack);
    padding: 0;
    display: flex;
    flex-wrap: wrap;
    gap: 0.25rem 0.75rem;
    font-size: 1.4rem;
    color: var(--bc-hub-muted);
}

.bc-hub-surface__steps li {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
}

.bc-hub-surface__steps li::before {
    content: "";
    display: inline-block;
    /* Slightly larger + thicker border than the original 0.6rem/2px combo.
       The current-step state uses a Butte-gold fill (--bc-hub-fill-gold,
       #FFC629) that on its own would only hit ~1.7:1 against white — well
       below the WCAG 1.4.11 3:1 bar for UI components. We let the dark
       outer ring (--bc-hub-accent-strong, ~9.7:1 on white) carry the
       contrast, and bump the border to 3px so the ring is unambiguously
       the dot's identifying edge in any zoom level / forced-colors mode. */
    width: 0.75rem;
    height: 0.75rem;
    border-radius: 50%;
    border: 3px solid var(--bc-hub-border-strong);
    background: var(--bc-hub-bg);
    box-sizing: border-box;
}

.bc-hub-surface__steps li[aria-current="step"] {
    color: var(--bc-hub-ink);
    font-weight: 700;
}

.bc-hub-surface__steps li[aria-current="step"]::before {
    background: var(--bc-hub-fill-gold);
    border-color: var(--bc-hub-accent-strong);
}

.bc-hub-surface__steps li[data-complete="true"]::before {
    background: var(--bc-hub-fill-dark);
    border-color: var(--bc-hub-fill-dark);
}

/* Narrow-viewport progress: dots + labels for five steps look messy
   at phone widths (any layout that fits has orphan items wrapping
   alone). Replace with plain "Step X of 5: <name>" text — clean,
   single line, no visual chrome.
       Step 4 of 5: Help needed
   Non-current <li>s remain in the DOM as visually-hidden elements so
   screen readers can still navigate the full progress sequence and
   hear each step name and position. */
@media (max-width: 40rem) {
    .bc-hub-surface__steps {
        display: block;
        font-weight: 400;
    }
    .bc-hub-surface__steps li:not([aria-current="step"]) {
        position: absolute;
        width: 1px;
        height: 1px;
        padding: 0;
        margin: -1px;
        overflow: hidden;
        clip: rect(0, 0, 0, 0);
        white-space: nowrap;
        border: 0;
    }
    .bc-hub-surface__steps li[aria-current="step"] {
        display: block;
        font-weight: 700;
        color: var(--bc-hub-ink);
    }
    /* Hide the colored dot — the prose "Step X of N: Name" carries
       all the progress information sighted users need. */
    .bc-hub-surface__steps li[aria-current="step"]::before {
        display: none;
    }
    /* Promote the screen-reader-only "Step X of N:" prefix to visible
       so the compact mobile layout shows position information. */
    .bc-hub-surface__steps li[aria-current="step"] .bc-hub-surface__sr {
        position: static;
        width: auto;
        height: auto;
        margin: 0 0.3em 0 0;
        padding: 0;
        overflow: visible;
        clip: auto;
        white-space: normal;
        border: 0;
        color: var(--bc-hub-muted);
        font-weight: 400;
    }
}

/* Visually-hidden text for screen readers (e.g., "Step 2 of 3:") */
.bc-hub-surface__sr {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

/* ----- Buttons ----- */

/* Button defaults — the bare-<button> selector is wrapped in :where()
   so its element-selector specificity (otherwise 0,1,1) drops to the
   same (0,1,0) as .bc-hub-surface__btn. That lets the --ghost and
   --dark modifier classes win on cascade order rather than fighting
   an over-specific descendant rule. */
.bc-hub-surface__btn,
:where(.bc-hub-surface button) {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.4rem;
    min-height: 44px; /* AAA touch target */
    min-width: 44px;
    padding: 0.6rem 1.1rem;
    font: inherit;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    line-height: 1.1;
    border: 2px solid transparent;
    border-radius: var(--bc-hub-radius-sm);
    cursor: pointer;
    background: var(--bc-hub-fill-gold);
    color: var(--bc-hub-fill-gold-on);
    text-decoration: none;
}

.bc-hub-surface__btn:hover,
:where(.bc-hub-surface button):hover {
    background: var(--bc-hub-fill-gold-hover);
}

.bc-hub-surface__btn:focus-visible,
:where(.bc-hub-surface button):focus-visible {
    outline: 3px solid var(--bc-hub-accent-strong);
    outline-offset: 2px;
}

.bc-hub-surface__btn:disabled,
:where(.bc-hub-surface button):disabled {
    background: var(--bc-hub-bg-alt);
    color: var(--bc-hub-muted);
    cursor: not-allowed;
    border-color: var(--bc-hub-border);
}

/* Secondary / ghost button — for "Back", "Start over" */
.bc-hub-surface__btn--ghost {
    background: transparent;
    color: var(--bc-hub-ink);
    border-color: var(--bc-hub-border-strong);
}

.bc-hub-surface__btn--ghost:hover {
    background: var(--bc-hub-bg-alt);
}

/* Dark / strong button — used when sending to an external booking page */
.bc-hub-surface__btn--dark {
    background: var(--bc-hub-fill-dark);
    color: var(--bc-hub-fill-dark-on);
}

.bc-hub-surface__btn--dark:hover {
    background: var(--bc-hub-fill-dark-hover);
}

/* External link icon affordance — uses ::after to keep markup clean */
.bc-hub-surface__btn[data-external="true"]::after,
.bc-hub-surface a[data-external="true"]::after {
    content: " \2197"; /* north-east arrow */
    display: inline-block;
    margin-left: 0.15em;
    font-weight: 700;
    speak: none;
}

/* ----- Form controls ----- */

.bc-hub-surface__field-group {
    border: 1px solid var(--bc-hub-border);
    border-radius: var(--bc-hub-radius);
    padding: 0.75rem 1rem 1rem;
    margin: 0;
}

.bc-hub-surface__field-group legend {
    padding: 0 0.4rem;
    font-weight: 700;
    font-size: 1.4rem;
    color: var(--bc-hub-ink);
}

.bc-hub-surface__field-group p {
    margin: 0.25rem 0 0.75rem;
    color: var(--bc-hub-muted);
    font-size: 1.4rem;
}

.bc-hub-surface__option {
    display: flex;
    align-items: flex-start;
    gap: 0.6rem;
    padding: 0.6rem 0.5rem;
    border-radius: var(--bc-hub-radius-sm);
    cursor: pointer;
    border: 1px solid transparent;
    min-height: 44px;
}

.bc-hub-surface__option:hover {
    background: var(--bc-hub-bg-alt);
    border-color: var(--bc-hub-border);
}

.bc-hub-surface__option input[type="checkbox"],
.bc-hub-surface__option input[type="radio"] {
    flex: 0 0 auto;
    width: 1.25rem;
    height: 1.25rem;
    margin: 0.1rem 0 0;
    accent-color: var(--bc-hub-accent-strong);
    cursor: pointer;
}

.bc-hub-surface__option input:focus-visible {
    outline: 3px solid var(--bc-hub-accent-strong);
    outline-offset: 3px;
    border-radius: 2px;
}

.bc-hub-surface__option-label {
    display: block;
    font-weight: 600;
    color: var(--bc-hub-ink);
    line-height: 1.3;
}

.bc-hub-surface__option-help {
    display: block;
    margin-top: 0.15rem;
    font-size: 1.4rem;
    font-weight: 400;
    color: var(--bc-hub-muted);
}

/* ----- Card / result panel ----- */

.bc-hub-surface__card {
    background: var(--bc-hub-bg-alt);
    border: 1px solid var(--bc-hub-border);
    border-left: 4px solid var(--bc-hub-accent-strong);
    border-radius: var(--bc-hub-radius);
    padding: 1rem 1.1rem;
}

.bc-hub-surface__card--primary {
    border-left-color: var(--bc-hub-fill-dark);
}

.bc-hub-surface__card-title {
    margin: 0 0 0.4rem;
    font-size: 1.5rem;
    font-weight: 700;
    line-height: 1.25;
    color: var(--bc-hub-ink);
}

.bc-hub-surface__card-meta {
    margin: 0 0 0.6rem;
    font-size: 1.4rem;
    color: var(--bc-hub-muted);
}

.bc-hub-surface__card dl {
    margin: 0.5rem 0 0;
    display: grid;
    grid-template-columns: max-content 1fr;
    gap: 0.25rem 0.75rem;
}

.bc-hub-surface__card dt {
    font-weight: 600;
    color: var(--bc-hub-muted);
}

.bc-hub-surface__card dd { margin: 0; }

/* ----- Status / live region ----- */

.bc-hub-surface__status {
    margin: 0;
    padding: 0.5rem 0.75rem;
    border-radius: var(--bc-hub-radius-sm);
    font-size: 1.4rem;
}

.bc-hub-surface__status--info {
    background: #eaf3f0;
    color: var(--bc-hub-success-text);
    border-left: 4px solid var(--bc-hub-success-text);
}

.bc-hub-surface__status--error {
    background: #fbeaea;
    color: var(--bc-hub-error-text);
    border-left: 4px solid var(--bc-hub-error-text);
}

/* Status icons use unicode symbols + text — never color alone */
.bc-hub-surface__status--info::before { content: "\2139\FE0F  "; } /* info i */
.bc-hub-surface__status--error::before { content: "\26A0\FE0F  "; } /* warning */

/* ----- Responsive layout ----- */

.bc-hub-surface__row {
    display: flex;
    flex-wrap: wrap;
    gap: var(--bc-hub-gutter);
    align-items: stretch;
}

.bc-hub-surface__row > * {
    flex: 1 1 16rem;
    min-width: 0;
}

/* Small viewports — collapse footer button row */
@media (max-width: 30rem) {
    .bc-hub-surface__footer {
        justify-content: stretch;
        flex-direction: column;
        align-items: stretch;
    }

    .bc-hub-surface__footer .bc-hub-surface__btn {
        width: 100%;
    }
}

/* ----- Reduced motion ----- */

@media (prefers-reduced-motion: no-preference) {
    .bc-hub-surface__btn,
    .bc-hub-surface__option {
        transition: background-color 120ms ease, border-color 120ms ease, color 120ms ease;
    }
}
