/* 
 * Blue Team - Robert Breutzmann, Miguel Fernandez, Carolina Rodriguez, Sara White
 * Primary Author/Owner - Shared (site-wide master stylesheet)
 * CSD 460 - Capstone Project - Marina Website Project
 * CSS Master File, Root Variables, Overall Site Styling
 */

/* ==========================================================================
   Moffat Bay Marina — Root Color Variables
   Link this file BEFORE any other stylesheet in the scaffold's <head>,
   so every page/component can reference these variables.

   Naming convention for anything added later:
      --color-<purpose>-<variant>, 
      e.g. --color-<cta>-<secondary-bg-hover>.
   ========================================================================== */

:root {
	/* --------------------------------------------------------------------
     1. Raw palette — the 6 approved colors, exactly as specified.
     Nothing outside this section should reference a hex value directly;
     everything else in this file (and every page's CSS) should reference
     the semantic variables below instead.
     -------------------------------------------------------------------- */
	--color-ocean-blue: #0a6e8c;
	--color-deep-marine: #0d3b4d;
	--color-sunset-coral: #ff6f59;
	--color-golden-hour: #f4a261;
	--color-sand: #e8d9b0;
	--color-charcoal-navy: #16262e;
	--color-surface-neutral: #ffffff;

	/* --------------------------------------------------------------------
     2. Semantic variables — what pages and components should actually
     reference. Grouped by purpose, not by color, so a page's CSS reads
     as "background: page background" instead of "background: sand."
     -------------------------------------------------------------------- */

	/* Page-level backgrounds */
	--color-bg-page: var(--color-sand);
	--color-bg-header: var(--color-deep-marine);
	--color-bg-footer: var(--color-deep-marine);
	--color-bg-surface: var(
		--color-surface-neutral
	); /* form fields, modals - full white, for input contrast */
	--color-bg-card: color-mix(
		in srgb,
		var(--color-ocean-blue) 6%,
		var(--color-surface-neutral)
	); /* card/panel grouping backgrounds - a light ocean-blue tint, distinct from both plain white and the sand page background */

	/* Text */
	--color-text-body: var(--color-charcoal-navy);
	--color-text-heading: var(--color-charcoal-navy);
	--color-text-inverse: var(
		--color-sand
	); /* text placed on header/footer/nav */
	--color-text-muted: var(
		--color-charcoal-navy
	); /* apply opacity in-context, e.g. color: var(--color-text-muted); opacity: 0.7; */

	/* Links (body copy, not nav — see Navigation below). Ocean blue taken a
	   fifth of the way toward deep marine: plain ocean blue is only 4.1:1 on
	   the sand page background, below WCAG AA's 4.5:1; this is 4.8:1 on
	   sand and better on every card. */
	--color-link: color-mix(in srgb, var(--color-ocean-blue) 80%, var(--color-deep-marine));
	--color-link-hover: var(--color-golden-hour);
	--color-link-visited: var(--color-link);

	/* Primary CTA — per the wireframe rules, only ONE per page.
	   Navy text, not white: white on coral is 2.74:1, below WCAG AA's 4.5:1
	   for button-size text. Navy is 5.68:1 on the coral and 7.54:1 on the
	   gold hover colour, so one value passes in both states. */
	--color-cta-primary-bg: var(--color-sunset-coral);
	--color-cta-primary-text: var(--color-charcoal-navy);
	--color-cta-primary-bg-hover: var(--color-golden-hour);

	/* Secondary buttons — every button on a page after the one primary CTA */
	--color-cta-secondary-bg: var(--color-ocean-blue);
	--color-cta-secondary-text: var(--color-surface-neutral);
	--color-cta-secondary-bg-hover: var(--color-golden-hour);

	/* Navigation (header nav links, distinct from body links above since
     they sit on a dark background) */
	--color-nav-bg: var(--color-deep-marine);
	--color-nav-text: var(--color-sand);
	--color-nav-text-hover: var(--color-golden-hour);
	--color-nav-text-active: var(
		--color-golden-hour
	); /*pairs with the activePage highlighting from header.jsp */

	/* Forms / inputs (Registration, Login modal, Contact, Reservation, etc.) */
	--color-input-bg: var(--color-bg-surface);
	--color-input-border: var(--color-charcoal-navy);
	--color-input-border-focus: var(--color-ocean-blue);
	--color-input-text: var(--color-charcoal-navy);

	/* Borders / dividers */
	--color-border: var(--color-charcoal-navy);

	/* Overlays — dark layer behind an open modal (Login modal, etc.) */
	--color-overlay-backdrop: color-mix(
		in srgb,
		var(--color-charcoal-navy) 70%,
		transparent
	);

	/* Record field badge - a stored value shown read-only, label above value.
     Golden hour is the one palette accent otherwise used only for hovers, so
     these never compete with an ocean-blue status pill sitting above them.
     The label is golden hour carried 45% of the way to the body text colour:
     5.33:1 on the badge fill and 5.50:1 on a card, which matters because it
     is the smallest text on the page. */
	--color-record-badge-bg: color-mix(
		in srgb,
		var(--color-golden-hour) 17%,
		var(--color-surface-neutral)
	);
	--color-record-badge-border: var(--color-golden-hour);
	--color-record-badge-label: color-mix(
		in srgb,
		var(--color-golden-hour) 45%,
		var(--color-charcoal-navy)
	);
	--color-record-badge-value: var(--color-deep-marine);

	/* Status pill - "what is this thing doing right now". Two tints: the
     active/known state in ocean blue, the neutral/idle state in the body
     colour, both light enough to read dark text on. */
	--color-status-active-bg: color-mix(
		in srgb,
		var(--color-ocean-blue) 12%,
		transparent
	);
	--color-status-active-text: var(--color-deep-marine);
	--color-status-idle-bg: color-mix(
		in srgb,
		var(--color-charcoal-navy) 7%,
		transparent
	);
	--color-status-idle-text: var(--color-charcoal-navy);

	/* Status colors */
	--color-error: #b3261e;
	--color-success: var(--color-ocean-blue);

	/* --------------------------------------------------------------------
     3. Layout metrics — the non-color values that more than one component
     has to agree on. Same rule as the colors above: reference the variable,
     don't retype the number.
     -------------------------------------------------------------------- */

	/* Height of the sticky site header. Anything else that sticks to the top
     of the window has to come to rest below it rather than under it (the
     Reservation Summary card is the one that does today), and the header
     paints over anything that doesn't. header.css pins .site-header to this
     instead of letting its contents decide the height, so the two sides
     can't drift apart.
     72px, a little above what the header's contents come to on their own
     (the 36px logo, its baseline gap, and 0.9rem of padding top and bottom,
     ~70px in Chrome). Being the taller of the two is the point: the header
     is then exactly this tall whatever the browser does with the font, so
     the number here is the header's height rather than a guess at it. */
	--header-height: 4.5rem;

	/* Corner radii. One per kind of object, so the same kind of thing has
     the same corners on every page:
       --radius-card     a card or panel sitting on the page
       --radius-inner    a card nested inside another card - one step
                         smaller, since a nested corner reads wrong when it
                         matches the box around it
       --radius-control  inputs, selects, buttons, banners
       --radius-pill     fully rounded tags and status pills
     Modals keep their own larger 14px - they float above the page rather
     than sitting on it. */
	--radius-card: 10px;
	--radius-inner: 8px;
	--radius-control: 6px;
	--radius-pill: 999px;

	/* Content column widths. Every page's main column uses one of these,
     so the content edges stay put as you move between pages:
       --content-narrow  forms, reading pages and single cards
       --content-wide    multi-column layouts (Registration's three
                         columns, Book a Slip's form and summary, card grids)
     The exceptions are pages that are a single card rather than a column -
     the error page, the coming-soon page and the Reservation Summary
     receipt - which are sized to their card. */
	--content-narrow: 60rem;
	--content-wide: 72rem;

	/* --------------------------------------------------------------------
     4. Typography. Georgia for headings, Segoe UI for everything else.
     Headings are set in plain Georgia, sentence or title case - no small
     caps, no letter-spaced capitals - so a heading looks the same on
     every page.
     -------------------------------------------------------------------- */
	--font-heading: Georgia, "Times New Roman", serif;
	--font-body: "Segoe UI", Arial, sans-serif;
}

/* ==========================================================================
   Breakpoints. Custom properties can't be used inside @media, so these are
   written out as numbers - use only these three, max-width, in rem so they
   follow the reader's font size:
     40rem (640px)   phone: columns stack, buttons go full width
     56rem (896px)   tablet: the header collapses to its menu button and
                     two-column layouts become one
     72rem (1152px)  wide: only for layouts that need extra room
   ========================================================================== */

/* ==========================================================================
   Global site styles
   ========================================================================== */

* {
    box-sizing: border-box;
}

html {
    height: 100%;
}

body {
    margin: 0;
    min-height: 100%;
    display: flex;
    flex-direction: column;
    font-family: var(--font-body);
    background: var(--color-bg-page);
    color: var(--color-text-body);
}

/* Browsers give buttons and form fields their own system font instead of
   the page's, which is why some buttons and fields read as unstyled. */
button,
input,
select,
textarea {
    font-family: inherit;
}

/* Sticky footer: every page's shell is header/main/footer as direct body
   children (see pageTemplate.jsp) - main grows to fill any leftover space
   so footer.jsp never sits mid-page on a short page, only pushed down by
   actual content on a tall one. */
main {
    flex: 1 0 auto;
}

a {
    color: var(--color-link);
}

a:hover {
    color: var(--color-link-hover);
}

/* ==========================================================================
   Salmon watermark — fixed behind the content of every page

   Lived in index.css until it became the site's backdrop rather than the
   landing page's. Fixed rather than scrolling, so it stays put as a page
   moves under it, and pointer-events: none so it can never intercept a
   click.

   main and .site-footer are lifted above it. .site-header is deliberately
   left alone: header.css already parks it at z-index 10 so it paints over
   anything that scrolls under it, and naming it here would quietly drop it
   to 1 on every page.
   ========================================================================== */

body::before {
    content: "";
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    z-index: 0;
    pointer-events: none;
    background-image: url("../images/SalishSalmon-FullTransparent.png");
    background-repeat: no-repeat;
    background-position: center center;
    background-size: 420px auto;
    opacity: 0.06;
}

main,
.site-footer {
    position: relative;
    z-index: 1;
}

/* ==========================================================================
   Shared component styles
   Classes used by more than one page, kept here so every page that loads
   site.css (via WEB-INF/includes/styles.jsp) gets them without importing another
   page's stylesheet.
   ========================================================================== */

/* --------------------------------------------------------------------------
   Hero band — full-width photo header with a dark gradient overlay and
   centered white text. The base owns everything a visitor reads as "the
   same banner": height, padding, heading type, lede, eyebrow and credit.
   A page's id adds only its photo and overlay strength, since every image
   has its bright spots in a different place behind the text.

   Two deliberate exceptions:
     - The landing hero is taller and louder than the rest because it is
       the site's first impression (#landingHero below).
     - Reservation Summary has no photo band at all. It is a receipt, so
       it opens with a check mark and a plain heading on the page
       (.summary-hero in reservationSummary.css) - a confirmation should
       read as a document, not as another banner.

   Markup every hero follows. It always sits outside <main>, between the
   site header and main, so it runs the full width of the window. The
   credit always reads "Image created with Google Gemini".
   It is a <section>, not a <header>: a <header> outside <main> is a
   second "banner" landmark next to the site header, and screen readers
   list both. aria-labelledby names the section after its own h1:

     <section class="hero-band" id="...Hero" aria-labelledby="...HeroTitle">
         <div class="hero-band__content">
             <p class="hero-band__eyebrow">optional category label</p>
             <h1 id="...HeroTitle">Title</h1>
             <p class="hero-band__lede">Subtitle</p>
         </div>
         <p class="hero-band__credit">optional image credit</p>
     </section>

   Base class:  .hero-band
   Used by: index.jsp             (#landingHero)
            registration.jsp      (#registrationHero)
            aboutUs.jsp           (#aboutHero)
            lookUpReservation.jsp (#lookUpReservationHero)
            reservation.jsp       (#reservationHero)
            myFleet.jsp           (#fleetHero)
            editUserInfo.jsp      (#accountHero)
            waitListLookup.jsp    (#waitListLookupHero)
            privacy.jsp           (#privacyHero)
            accessibility.jsp     (#accessibilityHero)
   -------------------------------------------------------------------------- */

.hero-band {
    position: relative;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    min-height: 17rem;
    padding: 3.5rem 1.5rem;
    background-color: var(--color-bg-header);
    background-size: cover;
    background-position: center;
    background-repeat: no-repeat;
    color: var(--color-text-inverse);
    text-align: center;
}

.hero-band h1 {
    margin: 0 0 0.75rem;
    font-family: var(--font-heading);
    font-weight: normal;
    font-size: clamp(2rem, 5vw, 3rem);
    line-height: 1.15;
    color: var(--color-text-inverse);
    text-shadow:
        0 2px 4px rgba(0, 0, 0, 0.8),
        0 0 12px rgba(0, 0, 0, 0.6);
}

.hero-band p {
    margin: 0;
    color: var(--color-text-inverse);
    text-shadow: 0 1px 4px rgba(0, 0, 0, 0.7);
}

/* Eyebrow text above the h1 - a category label for the page. */
.hero-band__eyebrow {
    margin: 0 0 0.5rem;
    font-size: 0.8rem;
    font-weight: bold;
    letter-spacing: 0.18em;
    text-transform: uppercase;
    opacity: 0.9;
}

/* Subtitle text below the h1. */
.hero-band__lede {
    font-size: 1.05rem;
    line-height: 1.5;
}

/* Small-print image credit, pinned to the bottom-right corner. */
.hero-band p.hero-band__credit {
    position: absolute;
    right: 0.9rem;
    bottom: 0.6rem;
    font-size: 0.7rem;
    letter-spacing: 0.04em;
    opacity: 0.75;
    text-shadow: 0 1px 3px rgba(0, 0, 0, 0.8);
}

/* Content container inside the hero — caps the text width. */
.hero-band__content {
    max-width: 46rem;
}

/* --------------------------------------------------------------------------
   Page-specific hero overrides — photo and overlay only.
   -------------------------------------------------------------------------- */

/* Registration, About Us, My Reservations, Waitlist Lookup, Privacy,
   Accessibility: Marina.jpg, 60% overlay. */
#registrationHero,
#aboutHero,
#lookUpReservationHero,
#waitListLookupHero,
#privacyHero,
#accessibilityHero {
    background-image:
        linear-gradient(rgba(13, 59, 77, 0.6), rgba(13, 59, 77, 0.6)),
        url("../images/Marina.jpg");
}

/* Reservation: Slip_Closeup.jpg, 48-62% gradient (the sunset horizon is
   bright orange right where the heading sits). */
#reservationHero {
    background-image:
        linear-gradient(rgba(13, 59, 77, 0.48), rgba(13, 59, 77, 0.62)),
        url("../images/Slip_Closeup.jpg");
}

/* My Fleet + Your Account: BoatYard_Sunset.jpg, a 58-70% gradient - heavier
   than any other hero on the site, and measured rather than guessed. The
   sun sits dead centre on the horizon, exactly where the heading goes, so
   this is the hardest backdrop any of our heroes has to carry light text
   over. At the Reservation hero's 48-62% the title only reaches 2.33:1
   against the brightest pixel behind it; 58-70% brings it to 2.99:1, just
   ahead of Reservation's own 2.76:1 and well ahead of the landing hero's
   1.73:1.

   Worth knowing: none of the site's heroes clear WCAG AA on that measure -
   they all lean on .hero-band h1's text-shadow, which helps a reader but
   earns no credit in the standard. Fixing that is a site-wide job. */
#fleetHero,
#accountHero {
    background-image:
        linear-gradient(rgba(13, 59, 77, 0.58), rgba(13, 59, 77, 0.7)),
        url("../images/BoatYard_Sunset.jpg");
}

/* Landing page: the one hero allowed to break the pattern. Marina.jpg with
   a light 22-32% overlay so the photo dominates, taller, and a bigger
   heading to anchor the first impression. Its description, tagline and
   call-to-action button are styled in index.css. */
#landingHero {
    min-height: 400px;
    background-image:
        linear-gradient(rgba(13, 59, 77, 0.22), rgba(13, 59, 77, 0.32)),
        url("../images/Marina.jpg");
}

#landingHero .hero-band__content {
    max-width: 780px;
}

#landingHero h1 {
    margin: 0 0 1.25rem;
    font-size: clamp(2.4rem, 5vw, 3.8rem);
    line-height: 1.1;
    text-shadow:
        0 2px 4px rgba(0, 0, 0, 0.95),
        0 0 12px rgba(0, 0, 0, 0.75);
}

/* --------------------------------------------------------------------------
   Form groups — label + input/select + error stacks.
   Used by: registration.jsp, aboutUs.jsp, reservation.jsp (boat panel),
            WEB-INF/includes/boatInfoCard.jsp, WEB-INF/includes/personalInfoCard.jsp
   -------------------------------------------------------------------------- */

.form-group {
    display: flex;
    flex-direction: column;
    gap: 0.35rem;
}

/* A hint or error written as a <p> under a field. The group's gap does the
   spacing; the browser's paragraph margins would add a second, larger gap
   under some fields and not others. */
.form-group > p {
    margin: 0;
}

.form-group label {
    font-size: 0.9rem;
    font-weight: 600;
    color: var(--color-text-heading);
    white-space: nowrap;
}

.form-group input,
.form-group select {
    padding: 0.7rem 0.8rem;
    border: 1px solid var(--color-input-border);
    border-radius: var(--radius-control);
    background: var(--color-input-bg);
    color: var(--color-input-text);
    font-size: 0.95rem;
    width: 100%;
}

/* Every form's example text. Lighter than typed text so an example can't
   be mistaken for an answer, but still about 4.9:1 on the white field -
   WCAG counts placeholder text as text, so it has to clear 4.5:1. Don't
   go below 65%: a 60% mix measures about 4.2:1. opacity: 1 because
   Firefox dims placeholders on top of whatever colour is set. */
::placeholder {
    color: color-mix(in srgb, var(--color-input-text) 65%, var(--color-input-bg));
    opacity: 1;
}

.form-group input:focus,
.form-group select:focus {
    outline: none;
    border-color: var(--color-input-border-focus);
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--color-ocean-blue) 15%, transparent);
}

.form-group input.field-invalid,
.form-group select.field-invalid {
    border-color: var(--color-error);
}

/* A field that can't be changed (Member since on Your Account, a reserved
   boat's length on My Fleet). Styled as a value rather than an empty box
   waiting for input, so nobody tries to type in it. */
.form-group input:disabled,
.form-group select:disabled {
    background: transparent;
    border-style: dashed;
    border-color: color-mix(in srgb, var(--color-border) 40%, transparent);
    color: var(--color-text-body);
    opacity: 1;
    cursor: not-allowed;
}

/* --------------------------------------------------------------------------
   Page column — the centred content column under a hero.
   Used by: registration.jsp (--wide), editUserInfo.jsp

   For a page whose <main> has no layout wrapper of its own. Pages that
   already have one (.fleet-page, .reservation-wrap, .lookup-page ...) set
   the same max-width from --content-narrow / --content-wide themselves.
   -------------------------------------------------------------------------- */

.page-column {
    width: 100%;
    max-width: var(--content-narrow);
    margin: 0 auto;
    padding: 2.5rem 1.5rem 4rem;
}

.page-column--wide {
    max-width: var(--content-wide);
}

/* --------------------------------------------------------------------------
   Form layout — a titled column of fields, and rows that split in two.
   Used by: registration.jsp, editUserInfo.jsp, reservation.jsp (boat
            panel), myFleet.jsp (boat modal), through
            WEB-INF/includes/personalInfoCard.jsp and WEB-INF/includes/boatInfoCard.jsp

   Moved from registration.css, which every one of those pages used to load
   just for these and so also picked up Registration's page width.
   -------------------------------------------------------------------------- */

.form-column {
    display: flex;
    flex-direction: column;
    gap: 1rem;
    background: var(--color-bg-card);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-card);
    padding: 1.5rem;
}

.column-heading {
    margin: 0;
    padding-bottom: 0.75rem;
    border-bottom: 1px solid var(--color-border);
    font-size: 1.1rem;
    color: var(--color-text-heading);
}

.form-group.field-narrow input {
    width: 6rem;
}

.form-row-split {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 1rem;
}

/* Country code + number. Stays side by side on a phone: the code box is
   narrow, and stacking it left a lone 3-character box on its own row. */
.form-row-split.form-row-split-phone {
    grid-template-columns: 3.5rem 1fr;
}

@media (max-width: 40rem) {
    .form-row-split:not(.form-row-split-phone) {
        grid-template-columns: 1fr;
    }
}

#phoneCountryCode {
    text-align: center;
}

.submit-row {
    margin-top: 0.5rem;
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
}

/* Keeps a label's layout space (so the country code box lines up with the
   Phone box beside it) without showing any text - the input carries its
   accessible name via aria-label instead, since visibility: hidden also
   hides it from most screen readers. */
.visually-hidden {
    visibility: hidden;
}

/* --------------------------------------------------------------------------
   Skip link — "Skip to main content", the first thing Tab reaches on every
   page (WEB-INF/includes/header.jsp). Off-screen until it has focus, then
   drops in over the top-left of the header. Above the sticky header and
   the modals so it's never hidden behind them.
   -------------------------------------------------------------------------- */

.skip-link {
    position: absolute;
    top: 0.5rem;
    left: 0.5rem;
    z-index: 1000;
    padding: 0.6rem 1rem;
    border-radius: var(--radius-control);
    background: var(--color-surface-neutral);
    color: var(--color-deep-marine);
    font-weight: bold;
    text-decoration: underline;
    transform: translateY(-200%);
}

.skip-link:focus {
    transform: none;
    outline: 2px solid var(--color-golden-hour);
    outline-offset: 2px;
}

/* <main> takes focus from the skip link (tabindex="-1"), but it isn't a
   control, so it shouldn't wear a focus ring. */
main:focus {
    outline: none;
}

/* --------------------------------------------------------------------------
   Sign-in panel — the signed-out view of every customer-only page.
   Used by: WEB-INF/includes/signInPanel.jsp, on reservation.jsp,
            lookUpReservation.jsp, reservationSummary.jsp, myFleet.jsp and
            editUserInfo.jsp
   -------------------------------------------------------------------------- */

.signin-panel {
    max-width: min(36rem, calc(100% - 2rem));
    margin: 2.5rem auto 4rem;
    padding: 2rem 1.5rem;
    text-align: center;
    background: var(--color-bg-card);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-card);
}

.signin-panel h1,
.signin-panel h2 {
    margin: 0 0 0.75rem;
    font-family: var(--font-heading);
    font-size: 1.35rem;
    font-weight: normal;
    color: var(--color-text-heading);
}

/* Reservation Summary has no hero, so its panel heading is the page's h1
   and is sized like one. */
.signin-panel h1 {
    font-size: clamp(1.75rem, 4vw, 2.25rem);
}

.signin-panel .btn-primary {
    margin: 0.5rem 0 1rem;
}

/* --------------------------------------------------------------------------
   Field error — validation message beneath a form field.
   Used by: registration.jsp, aboutUs.jsp, reservation.jsp,
            WEB-INF/includes/boatInfoCard.jsp
   -------------------------------------------------------------------------- */

.field-error {
    color: var(--color-error);
    font-size: 0.82rem;
}

/* No reserved space while there's no message. Not every field has an
   error slot, so reserving a line under the ones that do left uneven gaps
   down a form - wider under some fields than others. */
.field-error:empty {
    display: none;
}

/* --------------------------------------------------------------------------
   Required mark — the red asterisk after a label.
   Used by: registration.jsp, aboutUs.jsp, reservation.jsp,
            WEB-INF/includes/boatInfoCard.jsp
   -------------------------------------------------------------------------- */

.required-mark {
    color: var(--color-error);
}

/* --------------------------------------------------------------------------
   Field hint — secondary label text (e.g. "(optional)", "(recommended)").
   Used by: registration.jsp, aboutUs.jsp, reservation.jsp,
            WEB-INF/includes/boatInfoCard.jsp
   -------------------------------------------------------------------------- */

.field-hint {
    font-weight: 400;
    font-size: 0.8rem;
    /* Faded through the colour, not opacity: opacity would fade a link
       inside the hint too (Your Account's "Forgot your current
       password?"), taking it below WCAG AA's 4.5:1. */
    color: color-mix(in srgb, var(--color-text-muted) 75%, transparent);
    white-space: normal;
}

/* --------------------------------------------------------------------------
   Form banner — page-level success/error message above a form.
   Used by: registration.jsp, aboutUs.jsp, reservation.jsp
   -------------------------------------------------------------------------- */

.form-banner {
    max-width: var(--content-narrow);
    margin: 1.5rem auto 0;
    padding: 0.9rem 1.2rem;
    border-radius: var(--radius-control);
    background: color-mix(in srgb, var(--color-error) 8%, var(--color-surface-neutral));
    border: 1px solid var(--color-error);
    color: var(--color-error);
    font-size: 0.95rem;
}

.form-banner[hidden] {
    display: none;
}

.form-banner--success {
    background: color-mix(in srgb, var(--color-success) 8%, var(--color-surface-neutral));
    border-color: var(--color-success);
    color: var(--color-success);
}

/* --------------------------------------------------------------------------
   Callout badge — informational (non-error) notice inside a form card.
   Used by: registration.jsp (foreign-registration note),
            reservation.jsp (boat panel), WEB-INF/includes/boatInfoCard.jsp
            (including the over-50 ft length warning)
   -------------------------------------------------------------------------- */

.callout-badge {
    display: block;
    margin: 0.25rem 0 0.5rem;
    padding: 0.75rem 1rem;
    border-radius: var(--radius-control);
    background: color-mix(in srgb, var(--color-golden-hour) 18%, var(--color-surface-neutral));
    border: 1px solid var(--color-golden-hour);
    color: var(--color-text-body);
    font-size: 0.85rem;
    line-height: 1.4;
}

.callout-badge[hidden] {
    display: none;
}

.callout-badge a {
    font-weight: 600;
}

/* --------------------------------------------------------------------------
   Buttons. Four shared classes and one modifier - no page defines its own:

     .btn-primary   coral. The one main action of a view - one per page,
                    and one per open popup ("Create Account", "Reserve My
                    Slip", "Save Changes" in a popup).
     .btn-action    filled ocean blue. Any other action that does something
                    or goes somewhere ("Apply Filters", "Edit", "Go to My
                    Reservations").
     .btn-outline   outlined ocean blue. The lesser choice beside another
                    button, or a quiet one ("Cancel", "Keep Editing",
                    "Clear Personal Info").
     .btn-on-dark   outlined in light sand, for a dark background.
     .btn-danger    add to .btn-outline (offers a destructive action) or
                    .btn-action (confirms it).
   -------------------------------------------------------------------------- */

.btn-primary {
    display: inline-block;
    background: var(--color-cta-primary-bg);
    color: var(--color-cta-primary-text);
    border: none;
    padding: 0.85rem 1.5rem;
    border-radius: var(--radius-control);
    font-family: inherit;
    font-size: 1rem;
    font-weight: 600;
    text-decoration: none;
    cursor: pointer;
    align-self: flex-start;
}

.btn-primary:hover:not(:disabled) {
    background: var(--color-cta-primary-bg-hover);
    color: var(--color-cta-primary-text);
}

.btn-primary:disabled {
    opacity: 0.5;
    cursor: not-allowed;
}

/* --------------------------------------------------------------------------
   Button on a dark background (was .btn-secondary). Not used on a page
   today - the header's Log In / Log Out are .nav-cta - but kept so a
   button over a hero or the footer has a shared style to reach for.
   -------------------------------------------------------------------------- */

.btn-on-dark {
    display: inline-block;
    background: transparent;
    color: var(--color-cta-secondary-text);
    border: 1px solid var(--color-cta-secondary-text);
    padding: 0.75rem 1.4rem;
    border-radius: var(--radius-control);
    font-size: 0.95rem;
    font-weight: 600;
    text-decoration: none;
}

.btn-on-dark:hover {
    background: var(--color-cta-secondary-bg-hover);
    border-color: var(--color-cta-secondary-bg-hover);
    color: var(--color-charcoal-navy);
}

/* --------------------------------------------------------------------------
   "What changed" summary and the confirmation step.
   Used by: editUserInfo.jsp (inline, beneath the form),
            myFleet.jsp (inside the Edit modal)

   Moved here from editUserInfo.css when My Fleet became the second user of
   the same rows. What differs between the two pages is the box around them,
   which each page still owns - Edit User Info shows its confirmation inline
   on purpose, so the fields it is asking about stay visible behind it, while
   My Fleet's is already inside a modal because its form is.
   -------------------------------------------------------------------------- */

.change-summary__title {
	margin: 0 0 0.6rem;
	font-weight: 600;
}

.change-summary__list {
	margin: 0;
}

/* The label keeps its own column and the old → new change always sits
   beside it, wrapping inside that column when it is long. Letting the whole
   row wrap put short changes beside their label and long ones (phone
   numbers) underneath, so rows in the same list didn't line up. Phones
   stack every row instead - see the media query below. */
.change-summary__row {
	display: flex;
	flex-wrap: nowrap;
	align-items: baseline;
	gap: 0.5rem;
	padding: 0.3rem 0;
}

.change-summary__row + .change-summary__row {
	border-top: 1px solid color-mix(in srgb, var(--color-border) 40%, transparent);
}

.change-summary__row dt {
	flex: 0 0 9rem;
	margin: 0;
	color: var(--color-text-muted);
	font-size: 0.85rem;
	font-weight: 600;
}

.change-summary__row dd {
	flex: 1 1 0;
	display: flex;
	flex-wrap: wrap;
	align-items: baseline;
	gap: 0.5rem;
	margin: 0;
	min-width: 0;
	overflow-wrap: anywhere;
}

/* The old value is struck through as well as faded - the arrow and the
   colour shouldn't be the only things saying which one is gone. */
.change-summary__old {
	color: var(--color-text-muted);
	opacity: 0.75;
	text-decoration: line-through;
}

.change-summary__arrow {
	color: var(--color-text-muted);
	opacity: 0.6;
}

.change-summary__new {
	font-weight: 600;
}

@media (max-width: 40rem) {
	.change-summary__row {
		flex-wrap: wrap;
	}

	.change-summary__row dt,
	.change-summary__row dd {
		flex-basis: 100%;
	}
}

.confirm-changes {
	max-width: 46rem;
	margin: 0.5rem 0 0;
	padding: 1.25rem 1.5rem;
	background: var(--color-bg-card);
	border: 1px solid var(--color-ocean-blue);
	border-radius: var(--radius-card);
}

.confirm-changes[hidden] {
	display: none;
}

.confirm-changes__title {
	margin: 0 0 0.75rem;
	color: var(--color-text-heading);
	font-size: 1.1rem;
}

.confirm-changes__actions {
	display: flex;
	flex-wrap: wrap;
	gap: 0.75rem;
	margin-top: 1.25rem;
}

/* --------------------------------------------------------------------------
   Card title — the name of the thing a card is about.
   Used by: myFleet.jsp (boat name)

   Plain Georgia like every other heading on the site (see Typography in
   :root). This and .modal__title were the only small-caps headings.
   -------------------------------------------------------------------------- */

.card-title {
    margin: 0 0 0.75rem;
    padding-bottom: 0.625rem;
    border-bottom: 1px solid
        color-mix(in srgb, var(--color-border) 18%, transparent);
    font-family: var(--font-heading);
    font-size: 1.4375rem;
    font-weight: normal;
    text-align: center;
    color: var(--color-deep-marine);
}

/* --------------------------------------------------------------------------
   Detail card — a bordered panel about one record.
   Used by: myFleet.jsp (one per boat), lookUpReservation.jsp (one per
   reservation) and waitListLookup.jsp (one per wait list the customer is
   on). One class for all three since #287; the two that sit inside a
   results panel add --nested.
   -------------------------------------------------------------------------- */

.detail-card {
    padding: 1.125rem;
    border: 1px solid
        color-mix(in srgb, var(--color-border) 22%, transparent);
    border-radius: var(--radius-card);
    /* Half-transparent, like .benefit-card on the landing page, so the
       salmon behind it reads through rather than being boxed out. */
    background: color-mix(in srgb, var(--color-bg-card) 50%, transparent);
    box-shadow: 0 6px 14px
        color-mix(in srgb, var(--color-charcoal-navy) 10%, transparent);
}

/* A card nested inside a tinted results panel (My Reservations, Your Place
   in Line): one radius step tighter, solid rather than see-through since
   the panel behind it is already a card, and no shadow. Its title is ruled
   off from the details under it. */
.detail-card--nested {
    padding: 1.5rem;
    border-radius: var(--radius-inner);
    background: var(--color-bg-surface);
    box-shadow: none;
}

.detail-card--nested h3 {
    margin: 0 0 1rem;
    padding-bottom: 0.75rem;
    border-bottom: 1px solid
        color-mix(in srgb, var(--color-border) 18%, transparent);
    font-family: var(--font-heading);
    font-size: 1.2rem;
    font-weight: normal;
    color: var(--color-deep-marine);
}

/* The buttons that act on the record (Cancel Reservation, Leave Wait List),
   ruled off along the bottom of the card, with an optional hint beside
   them. The buttons are .btn-outline (+ .btn-danger). */
.detail-card__actions {
    margin-top: 1.25rem;
    padding-top: 0.75rem;
    border-top: 1px solid
        color-mix(in srgb, var(--color-border) 18%, transparent);
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.625rem;
}

.detail-card__hint {
    font-size: 0.8rem;
    line-height: 1.4;
    color: var(--color-text-muted);
    opacity: 0.85;
}

@media (max-width: 40rem) {
    .detail-card--nested {
        padding: 1.25rem;
    }

    .detail-card__actions > button {
        flex: 1 1 100%;
    }
}

/* --------------------------------------------------------------------------
   Record badges — a record's stored fields, read-only, label above value.
   Used by: myFleet.jsp

   Every column is a max-content track, so each badge is exactly as wide as
   the longest value in its own column and no wider; space-around then sits
   the columns in from the card's edges. The COLUMN COUNT belongs to the
   page, since it depends on how wide the card is — see .fleet-badges in
   myFleet.css.

   A field with nothing stored keeps its badge and goes dashed rather than
   being left out, so an owner can see what is missing and add it.
   -------------------------------------------------------------------------- */

.record-badges {
    display: grid;
    gap: 0.625rem 1rem;
    justify-content: space-around;
}

.record-badge {
    padding: 0.4375rem 0.75rem;
    border: 1px solid var(--color-record-badge-border);
    border-radius: var(--radius-control);
    background: var(--color-record-badge-bg);
    text-align: center;
}

.record-badge__label {
    display: block;
    margin-bottom: 0.25rem;
    padding-bottom: 0.1875rem;
    border-bottom: 1px solid
        color-mix(in srgb, var(--color-record-badge-label) 30%, transparent);
    font-size: 0.625rem;
    font-weight: 600;
    letter-spacing: 0.07em;
    text-transform: uppercase;
    color: var(--color-record-badge-label);
}

.record-badge__value {
    font-size: 0.875rem;
    line-height: 1.3;
    font-weight: 600;
    color: var(--color-record-badge-value);
}

.record-badge--empty {
    border-style: dashed;
    border-color: color-mix(in srgb, var(--color-border) 28%, transparent);
    background: transparent;
}

.record-badge--empty .record-badge__value {
    font-weight: normal;
    color: var(--color-text-muted);
    opacity: 0.55;
}

/* --------------------------------------------------------------------------
   Status pill — what a record is doing right now.
   Used by: myFleet.jsp (reserved / open to reserve)

   Always rendered, never only-when-interesting: a boat with no reservation
   is still an answer to "what is this doing", and a badge that shows up only
   sometimes reads as a glitch when it does.
   -------------------------------------------------------------------------- */

.status-pill-row {
    display: flex;
    justify-content: center;
    margin-bottom: 1rem;
}

.status-pill {
    margin: 0;
    display: inline-flex;
    align-items: baseline;
    flex-wrap: wrap;
    justify-content: center;
    gap: 0.1875rem 0.5625rem;
    padding: 0.375rem 0.875rem;
    border-radius: var(--radius-pill);
    font-size: 0.8125rem;
    line-height: 1.4;
    text-align: center;
}

.status-pill__dot {
    font-size: 0.9375rem;
}

.status-pill__label {
    font-weight: 600;
}

.status-pill__detail {
    color: var(--color-text-muted);
    opacity: 0.8;
}

.status-pill__code {
    font-weight: 500;
    color: var(--color-text-muted);
    opacity: 0.8;
}

.status-pill--active {
    background: var(--color-status-active-bg);
    color: var(--color-status-active-text);
}

.status-pill--active .status-pill__dot {
    color: var(--color-ocean-blue);
}

.status-pill--idle {
    background: var(--color-status-idle-bg);
    color: var(--color-status-idle-text);
}

.status-pill--idle .status-pill__dot {
    color: var(--color-text-muted);
    opacity: 0.5;
}

/* --------------------------------------------------------------------------
   Modal — backdrop, centred box, header with a close button.
   Used by: every popup on the site - myFleet.jsp (Add/Edit a boat, Remove
            confirmation), lookUpReservation.jsp (Cancel, 30-day notice),
            editUserInfo.jsp (Save these changes?), reservation.jsp (boat
            panel, Book this slip?), and the account popups in
            WEB-INF/includes/loginModal.jsp, forgotPasswordModal.jsp and
            changePasswordModal.jsp. Open/close: js/modal.js

   One backdrop, one close button, one Escape and focus handler for all of
   them, so a fix to how popups behave is made once.
   -------------------------------------------------------------------------- */

.modal[hidden] {
    display: none;
}

/* main is z-index 1 (it sits above the salmon watermark), which makes it a
   stacking context: a popup inside it could never rise above the sticky
   site header (z-index 10), so a tall popup's title slid under the header.
   While one is open, main itself goes above the header. */
main:has(.modal:not([hidden])) {
    z-index: 101;
}

.modal {
    position: fixed;
    inset: 0;
    z-index: 100;
    display: flex;
    align-items: flex-start;
    justify-content: center;
    padding: 1.5rem;
    overflow-y: auto;
}

.modal__backdrop {
    position: fixed;
    inset: 0;
    border: none;
    padding: 0;
    background: var(--color-overlay-backdrop);
}

.modal__box {
    position: relative;
    width: min(38.75rem, 100%);
    margin: auto;
    padding: 1.625rem;
    border-radius: 14px;
    background: var(--color-bg-surface);
    box-shadow: 0 18px 44px
        color-mix(in srgb, var(--color-deep-marine) 35%, transparent);
}

.modal__header {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 1rem;
    margin-bottom: 0.875rem;
    padding-bottom: 0.875rem;
    border-bottom: 1px solid
        color-mix(in srgb, var(--color-border) 18%, transparent);
}

.modal__title {
    margin: 0;
    font-family: var(--font-heading);
    font-size: 1.3125rem;
    font-weight: normal;
    color: var(--color-deep-marine);
}

.modal__close {
    min-width: 44px;
    min-height: 44px;
    margin: -0.625rem -0.5rem 0 0;
    border: none;
    background: transparent;
    font-size: 1.375rem;
    line-height: 1;
    color: var(--color-text-muted);
    cursor: pointer;
}

.modal__close:hover {
    color: var(--color-link-hover);
}

.modal__actions {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: 0.625rem;
    flex-wrap: wrap;
    margin-top: 1.25rem;
    padding-top: 1rem;
    border-top: 1px solid
        color-mix(in srgb, var(--color-border) 18%, transparent);
}

/* A confirmation modal: one question, not a form. */
.modal__box--narrow {
    width: min(28rem, 100%);
}

/* The question a confirmation modal asks, and the smaller note under it. */
.modal__question {
    margin: 0 0 0.625rem;
    font-size: 1rem;
    line-height: 1.5;
    color: var(--color-text-body);
}

.modal__note {
    margin: 0;
    font-size: 0.84375rem;
    line-height: 1.5;
    color: var(--color-text-muted);
    opacity: 0.85;
}

/* --------------------------------------------------------------------------
   Action buttons on a light surface — a filled one and its outlined pair.
   See the button list above .btn-primary for when to use which.

   The 44px minimum is a touch target, not padding - it is what makes
   these usable on a phone, so it stays even when the type gets smaller.
   align-self keeps one from stretching across a column layout (the Clear
   buttons at the foot of a .form-column).
   -------------------------------------------------------------------------- */

.btn-action,
.btn-outline {
    align-self: flex-start;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-height: 44px;
    padding: 0.5625rem 1.25rem;
    border-radius: var(--radius-control);
    font-family: inherit;
    font-size: 0.875rem;
    font-weight: 600;
    text-decoration: none;
    cursor: pointer;
}

.btn-action {
    border: 1px solid var(--color-cta-secondary-bg);
    background: var(--color-cta-secondary-bg);
    color: var(--color-cta-secondary-text);
}

.btn-action:hover:not(:disabled) {
    background: var(--color-cta-secondary-bg-hover);
    border-color: var(--color-cta-secondary-bg-hover);
    color: var(--color-charcoal-navy);
}

.btn-outline {
    border: 1px solid var(--color-cta-secondary-bg);
    background: transparent;
    color: var(--color-cta-secondary-bg);
}

.btn-outline:hover:not(:disabled) {
    background: var(--color-cta-secondary-bg-hover);
    border-color: var(--color-cta-secondary-bg-hover);
    color: var(--color-charcoal-navy);
}

/* Keyboard focus, the same ring on every shared button. */
.btn-primary:focus-visible,
.btn-action:focus-visible,
.btn-outline:focus-visible,
.btn-on-dark:focus-visible {
    outline: 2px solid var(--color-input-border-focus);
    outline-offset: 2px;
}

.btn-on-dark:focus-visible {
    outline-color: var(--color-sand);
}

.btn-action:disabled,
.btn-outline:disabled {
    opacity: 0.5;
    cursor: not-allowed;
}

/* Destructive: add to either one above - an outlined red button that
   offers the action, a filled red one that confirms it.
   Used by: lookUpReservation.jsp (Cancel Reservation) */
.btn-outline.btn-danger {
    border-color: var(--color-error);
    color: var(--color-error);
}

.btn-action.btn-danger {
    border-color: var(--color-error);
    background: var(--color-error);
    color: var(--color-surface-neutral);
}

.btn-outline.btn-danger:hover:not(:disabled),
.btn-action.btn-danger:hover:not(:disabled) {
    border-color: color-mix(in srgb, var(--color-error) 85%, black);
    background: color-mix(in srgb, var(--color-error) 85%, black);
    color: var(--color-surface-neutral);
}
