/* Theme base styles */

/* Settings
Design tokens (color, spacing, radius, type, shadow, z-index) as CSS custom
properties. Must load first so every downstream rule can read var(--token).
Note: embedded modules don't load main.css — they re-declare the tokens they
need, scoped to their root class. See docs/design-tokens-audit.md.
*/

/* ==========================================================================
   Design tokens — single source of truth
   --------------------------------------------------------------------------
   ITCSS "Settings" layer. Included FIRST in main.css so every downstream
   component/element rule can read these custom properties.

   Values are LITERALS equal to today's hardcoded values — defining them is a
   no-op visually. Migration (replacing raw hex with var(--token)) happens in
   later batches; see docs/design-tokens-audit.md for the collapse decisions.

   CAVEAT: embedded modules (Availability Calendar, Event Listing) do
   NOT load main.css, so these :root tokens do not reach them. Those modules
   re-declare the block they need, scoped to their root class. Keep the two in
   sync — this file is the canonical list.

   Guardrail: a hex outside this palette should fail CI. Add a token here
   (with a documented reason) before introducing a new value.
   ========================================================================== */

:root {
  /* --- Brand ----------------------------------------------------------- */
  --color-brand-green: #2f7751; /* primary; ==  */
  --color-brand-green-dark: #245c3d; /* hover / active / accent borders */
  --color-navy: #1d3447; /* heading / secondary; ==  */
  --color-navy-light: #2a4a66; /* lighter navy (guest-pill text) */
  --color-brand-tint: #f0f7f4; /* light brand-green wash (selected/active rows) */
  --color-teal: #66ccb2; /* "Intermediate" difficulty badge (event detail) */
  --color-earth-brown: #8a5a2b; /* earthy brown — camp/tent report icon (ACC-1891) */

  /* --- Neutrals: text -------------------------------------------------- */
  --color-text: #333333; /* default strong text */
  --color-text-body: #444444; /* body copy (== body_font.color) */
  --color-text-secondary: #666666; /* secondary / subtext */
  --color-text-muted: #6c757d; /* UI muted (status pills, empty state) */

  /* --- Neutrals: backgrounds & borders (light -> dark) ----------------- */
  --color-white: #ffffff;
  --color-black: #000000;
  --color-bg-page: #f8f8f8; /* page background */
  --color-bg-subtle: #f5f5f5; /* light fill / hover row */
  --color-bg-muted: #efefef; /* card background */
  --color-border: #e0e0e0; /* default border / divider */
  --color-border-strong: #cccccc; /* stronger border */
  --color-border-input: #888888; /* field border: 3.5:1 on white (ACC-2025 D6) */
  --color-placeholder: #888888; /* placeholder / decorative grey */

  /* --- State: danger --------------------------------------------------- */
  --color-danger: #d32f2f; /* error border / icon */
  --color-danger-dark: #a82323; /* hover on a destructive button */
  --color-danger-text: #721c24; /* dark text on danger bg */
  --color-danger-bg: #f8d7da; /* light error fill */

  /* --- State: success -------------------------------------------------- */
  --color-success: #28a745; /* success border / icon */
  --color-success-text: #155724;
  --color-success-bg: #d4edda;

  /* --- State: warning -------------------------------------------------- */
  --color-warning: #ffc107; /* warning border / icon */
  --color-warning-text: #856404;
  --color-warning-bg: #fff3cd;

  /* --- State: info ----------------------------------------------------- */
  --color-info: #0073aa; /* info-box link / border */
  --color-info-cyan: #17a2b8; /* info-pill accent */
  --color-info-text: #0c5460;
  --color-info-bg: #e8f4fc;

  /* --- Third-party attribution -------------------------------------- */
  /* Fixed by Google's attribution policy, not a palette choice: the "Google
     Maps" credit beside a Google address suggestion (ACC-1770). */
  --color-google-attribution: #5e5e5e;

  /* --- Overlays & focus ------------------------------------------------ */
  --color-overlay: rgba(0, 0, 0, 0.5); /* modal backdrop */
  --color-overlay-dark: rgba(0, 0, 0, 0.9); /* lightbox backdrop */
  --focus-ring-color: var(--color-brand-green); /* keyboard focus ring (D5) */

  /* --- Border radius --------------------------------------------------- */
  --radius-sm: 4px;
  --radius-md: 8px;
  --radius-lg: 12px;
  --radius-xl: 16px;
  --radius-button: 15px; /* dominant button / form radius */
  --radius-pill: 20px;
  --radius-circle: 50%;

  /* --- Controls (ACC-2025 D4, D6) -------------------------------------- */
  --control-height: 44px; /* buttons and fields share a height */
  --control-height-compact: 36px; /* filter-bar fields */
  --tap-target-min: 24px; /* WCAG 2.2 AA floor for compact inline controls */
  /* select chevron: navy (--color-navy) stroke, 16px */
  --icon-select-chevron: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 16 16'%3E%3Cpath d='M4 6l4 4 4-4' fill='none' stroke='%231d3447' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");

  /* --- Box shadow ------------------------------------------------------ */
  --shadow-sm: 0 2px 8px rgba(0, 0, 0, 0.08);
  --shadow-md: 0 4px 20px rgba(0, 0, 0, 0.15);
  --shadow-focus: 0 0 0 3px rgba(47, 119, 81, 0.25); /* field focus halo (D5) */
  --shadow-focus-danger: 0 0 0 3px rgba(211, 47, 47, 0.2); /* invalid field in focus */

  /* --- z-index --------------------------------------------------------- */
  --z-base: 1;
  --z-nav-overlay: 999; /* nav drawer dim overlay — must stay BELOW --z-dropdown
                           (drawer + header bar) so the open drawer is clickable */
  --z-dropdown: 1000;
  --z-sticky: 1002;
  --z-modal: 9999;
  --z-dialog: 10000; /* a confirm dialog: above a record sheet (--z-modal) it
                        opens over, whatever their order in <body> */
  --z-toast: 10001;

  /* --- Typography: size scale ------------------------------------------ */
  --font-size-2xs: 10px; /* dense data only: calendar day counts, table chips, card-replica text */
  --font-size-xs: 12px;
  --font-size-sm: 13px;
  --font-size-md: 14px;
  --font-size-base: 16px;
  --font-size-lg: 18px;
  --font-size-xl: 20px;
  --font-size-2xl: 22px;
  --font-size-3xl: 24px;

  /* --- Typography: weight ---------------------------------------------- */
  --font-weight-normal: 400;
  --font-weight-medium: 500;
  --font-weight-semibold: 600;
  --font-weight-bold: 700;

  /* --- Spacing scale (4 / 8 grid) -------------------------------------- */
  --space-1: 4px;
  --space-2: 8px;
  --space-3: 12px;
  --space-4: 16px;
  --space-5: 20px;
  --space-6: 24px;
  --space-8: 32px;
  --space-10: 40px;
  --space-12: 48px;
}

/* Tools
Any animations, or functions used throughout the project.
Note: _macros.css needs to be imported into each stylesheet where macros are used and not included here
*/

/* Generic
This is where reset, normalize & box-sizing styles go.
*/

*,
*:before,
*:after {
  box-sizing: border-box;
}
/*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */

/* Document
   ========================================================================== */

/**
 * 1. Correct the line height in all browsers.
 * 2. Prevent adjustments of font size after orientation changes in iOS.
 */

html {
  line-height: 1.15; /* 1 */
  -webkit-text-size-adjust: 100%; /* 2 */
}

/* Sections
   ========================================================================== */

/**
 * Remove the margin in all browsers.
 */

body {
  margin: 0;
}

/**
 * Correct the font size and margin on `h1` elements within `section` and
 * `article` contexts in Chrome, Firefox, and Safari.
 */

h1 {
  font-size: 2em;
  margin: 0.67em 0;
}

/* Grouping content
   ========================================================================== */

/**
 * Add the correct box sizing in Firefox.
 */

hr {
  box-sizing: content-box;
  height: 0;
}

/**
 * 1. Correct the inheritance and scaling of font size in all browsers.
 * 2. Correct the odd `em` font sizing in all browsers.
 */

pre {
  font-family: monospace, monospace; /* 1 */
  font-size: 1em; /* 2 */
}

/* Text-level semantics
   ========================================================================== */

/**
 * 1. Remove the bottom border in Chrome 57-
 * 2. Add the correct text decoration in Chrome, Edge, Opera, and Safari.
 */

abbr[title] {
  border-bottom: none; /* 1 */
  text-decoration: underline; /* 2 */
  text-decoration: underline dotted; /* 2 */
}

/**
 * Add the correct font weight in Chrome, Edge, and Safari.
 */

b,
strong {
  font-weight: bolder;
}

/**
 * 1. Correct the inheritance and scaling of font size in all browsers.
 * 2. Correct the odd `em` font sizing in all browsers.
 */

code,
kbd,
samp {
  font-family: monospace, monospace; /* 1 */
  font-size: 1em; /* 2 */
}

/**
 * Add the correct font size in all browsers.
 */

small {
  font-size: 80%;
}

/**
 * Prevent `sub` and `sup` elements from affecting the line height in
 * all browsers.
 */

sub,
sup {
  font-size: 75%;
  line-height: 0;
  position: relative;
  vertical-align: baseline;
}

sub {
  bottom: -0.25em;
}

sup {
  top: -0.5em;
}

/* Forms
   ========================================================================== */

/**
 * 1. Change the font styles in all browsers.
 * 2. Remove the margin in Firefox and Safari.
 */

button,
input,
optgroup,
select,
textarea {
  font-family: inherit; /* 1 */
  font-size: 100%; /* 1 */
  line-height: 1.15; /* 1 */
  margin: 0; /* 2 */
}

/**
 * Remove the inheritance of text transform in Edge and Firefox.
 * 1. Remove the inheritance of text transform in Firefox.
 */

button,
select {
  /* 1 */
  text-transform: none;
}

/**
 * Correct the inability to style clickable types in iOS and Safari.
 */

button,
[type='button'],
[type='reset'],
[type='submit'] {
  -webkit-appearance: button;
}

/**
 * Remove the inner border and padding in Firefox.
 */

button::-moz-focus-inner,
[type='button']::-moz-focus-inner,
[type='reset']::-moz-focus-inner,
[type='submit']::-moz-focus-inner {
  border-style: none;
  padding: 0;
}

/**
 * Restore the focus styles unset by the previous rule.
 */

button:-moz-focusring,
[type='button']:-moz-focusring,
[type='reset']:-moz-focusring,
[type='submit']:-moz-focusring {
  outline: 1px dotted ButtonText;
}

/**
 * Correct the padding in Firefox.
 */

fieldset {
  padding: 0.35em 0.75em 0.625em;
}

/**
 * Remove the padding so developers are not caught out when they zero out `fieldset` elements in all browsers.
 */

legend {
  padding: 0;
}

/**
 * Add the correct vertical alignment in Chrome, Firefox, and Opera.
 */

progress {
  vertical-align: baseline;
}

/**
 * Correct the cursor style of increment and decrement buttons in Chrome.
 */

[type='number']::-webkit-inner-spin-button,
[type='number']::-webkit-outer-spin-button {
  height: auto;
}

/**
 * 1. Correct the odd appearance in Chrome and Safari.
 * 2. Correct the outline style in Safari.
 */

[type='search'] {
  -webkit-appearance: textfield; /* 1 */
  outline-offset: -2px; /* 2 */
}

/**
 * Remove the inner padding in Chrome and Safari on macOS.
 */

[type='search']::-webkit-search-decoration {
  -webkit-appearance: none;
}

/**
 * 1. Correct the inability to style clickable types in iOS and Safari.
 * 2. Change font properties to `inherit` in Safari.
 */

::-webkit-file-upload-button {
  -webkit-appearance: button; /* 1 */
  font: inherit; /* 2 */
}

/* Interactive
   ========================================================================== */

/*
 * Add the correct display in Edge and Firefox.
 */

details {
  display: block;
}

/*
 * Add the correct display in all browsers.
 */

summary {
  display: list-item;
}

/* Objects
Non-cosmetic design patterns including grid and layout classes)
*/



/* CSS variables */

:root {
  --column-gap: 2.13%;
  --column-width-multiplier: 8.333;
}

/* Mobile layout */

.row-fluid {
  display: flex;
  flex-wrap: wrap;
  width: 100%;
}


  .row-fluid .span1,
  .row-fluid .span2,
  .row-fluid .span3,
  .row-fluid .span4,
  .row-fluid .span5,
  .row-fluid .span6,
  .row-fluid .span7,
  .row-fluid .span8,
  .row-fluid .span9,
  .row-fluid .span10,
  .row-fluid .span11,
  .row-fluid .span12{
  min-height: 1px;
  width: 100%;
}

/* Desktop layout */

@media (min-width: 768px) {
  .row-fluid {
    flex-wrap: nowrap;
    justify-content: space-between;
  }

  
    .row-fluid .span1 {
      width: calc(var(--column-width-multiplier) * 1% * 1 - var(--column-gap) * (11 * var(--column-width-multiplier) / 100));
    }
  
    .row-fluid .span2 {
      width: calc(var(--column-width-multiplier) * 1% * 2 - var(--column-gap) * (10 * var(--column-width-multiplier) / 100));
    }
  
    .row-fluid .span3 {
      width: calc(var(--column-width-multiplier) * 1% * 3 - var(--column-gap) * (9 * var(--column-width-multiplier) / 100));
    }
  
    .row-fluid .span4 {
      width: calc(var(--column-width-multiplier) * 1% * 4 - var(--column-gap) * (8 * var(--column-width-multiplier) / 100));
    }
  
    .row-fluid .span5 {
      width: calc(var(--column-width-multiplier) * 1% * 5 - var(--column-gap) * (7 * var(--column-width-multiplier) / 100));
    }
  
    .row-fluid .span6 {
      width: calc(var(--column-width-multiplier) * 1% * 6 - var(--column-gap) * (6 * var(--column-width-multiplier) / 100));
    }
  
    .row-fluid .span7 {
      width: calc(var(--column-width-multiplier) * 1% * 7 - var(--column-gap) * (5 * var(--column-width-multiplier) / 100));
    }
  
    .row-fluid .span8 {
      width: calc(var(--column-width-multiplier) * 1% * 8 - var(--column-gap) * (4 * var(--column-width-multiplier) / 100));
    }
  
    .row-fluid .span9 {
      width: calc(var(--column-width-multiplier) * 1% * 9 - var(--column-gap) * (3 * var(--column-width-multiplier) / 100));
    }
  
    .row-fluid .span10 {
      width: calc(var(--column-width-multiplier) * 1% * 10 - var(--column-gap) * (2 * var(--column-width-multiplier) / 100));
    }
  
    .row-fluid .span11 {
      width: calc(var(--column-width-multiplier) * 1% * 11 - var(--column-gap) * (1 * var(--column-width-multiplier) / 100));
    }
  
}
.content-wrapper {
  margin: 0 auto;
  padding: 0 1rem;
  max-width: 100%;
  box-sizing: border-box;
}

@media screen and (min-width: 1380px) {
  .content-wrapper {
    padding: 0;
  }
}

.dnd-section > .row-fluid {
  margin: 0 auto;
  align-items: flex-start;
}

.dnd-section .dnd-column {
  padding: 0 1rem;
}

@media (max-width: 767px) {
  .dnd-section .dnd-column {
    padding: 0;
  }
}

/* Elements
Base HMTL elements are styled in this section (<body>, <h1>, <a>, <p>, <button> etc.)
*/

/* The overflow-wrap is meant to prevent long/large words from breaking the mobile responsiveness of a page (e.g. horizontal scrolling). It is preferred to reduce font sizes on mobile to address this, with this CSS specifically helping with extreme scenarios where a reduction in font size is not possible. */

/* 16px body, independent of the theme editor's body-size setting (ACC-2028). */
body {
  font-size: var(--font-size-base);
  line-height: 1.5;
  overflow-wrap: break-word;
}

/* Handles word breaking for a few specific languages which handle breaks in words differently. If your content is not translated into these languages, you can safely remove this.  */

html[lang^='ja'] body,
html[lang^='zh'] body,
html[lang^='ko'] body {
  line-break: strict;
  overflow-wrap: normal;
  word-break: break-all;
}

/* Paragraphs */

p {
  margin: 0 0 1.4rem;
}

/* Long reading copy (event descriptions, rich text): a little more leading.
   No width cap: these columns already sit beside a sidebar (~80 characters),
   and a cap left their right edges uneven against the full-width blocks. */
.prose {
  line-height: 1.6;
}

.prose > :last-child {
  margin-bottom: 0;
}

/* Anchors */

a {
  cursor: pointer;
}

/* Headings */

h1,
h2,
h3,
h4,
h5,
h6 {
  margin: 0 0 1.4rem;
}

/* Lists */

ul,
ol {
  margin: 0 0 1.4rem;
}

ul ul,
ol ul,
ul ol,
ol ol {
  margin: 0;
}

ul.no-list {
  list-style: none;
  margin: 0;
  padding-left: 0;
}

/* Code blocks */

pre {
  overflow: auto;
}

code {
  vertical-align: bottom;
}

/* Blockquotes */

blockquote {
  border-left: 2px solid;
  margin: 0 0 1.4rem;
  padding-left: 0.7rem;
}

/* Horizontal rules */

hr {
  border: none;
  border-bottom: 1px solid var(--color-border-strong);
}

/* Image alt text */

img {
  font-size: var(--font-size-xs);
  word-break: normal;
}
/* ==========================================================================
   Buttons (ACC-2025: D3, D4, D5, D16; decisions in docs/style-audit.md §5,
   PR #220)

   One family: primary, secondary, text and danger, 44px by default and 32px
   small, one radius, sentence case. The theme's HubL button chrome now lands
   only on HubSpot-generated .button / .hs-button (theme-overrides.css), so a
   <button> starts neutral here and takes its look from a class.

   Legacy class names and HubSpot's own buttons are aliases in the selector
   lists below; the legacy names are removed after ACC-2025 PR D.
     .clickable-button            -> primary
     .clickable-button-secondary  -> secondary
     .button-link                 -> compact text button (24px tap floor; sits
                                     inline). .btn--text is the 44px target.
     .disabled-button(-link)      -> disabled
     .btn-primary / -secondary / -danger (modals), .acc-row-btn (rows)
   ========================================================================== */

/* Neutral base: no chrome until a class adds it. (normalize.css already sets
   margin and text-transform.) */
button {
  padding: 0;
  border: 0;
  border-radius: 0;
  background: none;
  color: inherit;
  font: inherit;
  line-height: 1.15;
  cursor: pointer;
}

button:disabled {
  cursor: not-allowed;
}

/* Keyboard focus (D5): one brand ring for every interactive element, shown
   for the keyboard only. */
:is(
    a,
    button,
    input[type='submit'],
    input[type='button'],
    input[type='checkbox'],
    input[type='radio'],
    summary
  ):focus-visible {
  outline: 2px solid var(--focus-ring-color);
  outline-offset: 2px;
}

/* A checkbox or radio inside its own label: the ring goes round the label,
   the whole click target, so it shows whatever the label is filled with (a
   brand-green pill, a chosen card), where a ring beside the small box could
   vanish into the fill. The box's own ring is hidden only where :has() works
   and the label carries it; elsewhere the box keeps it. */
label:has(> input:is([type='checkbox'], [type='radio']):focus-visible) {
  outline: 2px solid var(--focus-ring-color);
  outline-offset: 2px;
}

label:has(> input:is([type='checkbox'], [type='radio']):focus-visible)
  > input:focus-visible {
  outline-color: transparent;
}

/* Button State Utilities
   ========================================================================== */

.button-active {
  display: inline-flex !important;
}

.button-hidden {
  display: none !important;
}

/* Shape
   ========================================================================== */

.btn,
.clickable-button,
.clickable-button-secondary,
.btn-primary,
.btn-secondary,
.btn-danger,
.disabled-button,
.acc-row-btn,
form input[type='submit'],
form .hs-button,
.hs-search-field__button,
.button-wrapper--secondary a {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  min-height: var(--control-height);
  padding: 0 var(--space-5);
  border: 1px solid transparent;
  border-radius: var(--radius-button);
  font-size: var(--font-size-base);
  font-weight: var(--font-weight-semibold);
  line-height: 1.2;
  text-align: center;
  text-decoration: none;
  text-transform: none;
  cursor: pointer;
  transition: background-color 0.15s ease, border-color 0.15s ease,
    color 0.15s ease;
}

.btn--sm,
.acc-row-btn {
  min-height: 32px;
  padding: 0 var(--space-3);
  font-size: var(--font-size-sm);
}

/* Variants. Later rules win, so a secondary alias beats a primary one on the
   same element. Text colour is set on hover AND focus at >= 0-2-0: the
   theme's `a:hover, a:focus` colour (0-1-1, loaded last) would otherwise
   recolour an anchor button, e.g. after a click.
   ========================================================================== */

.btn--primary,
.clickable-button,
.btn-primary,
.acc-row-btn--primary,
form input[type='submit'],
form .hs-button,
.hs-search-field__button {
  background-color: var(--color-brand-green);
  border-color: var(--color-brand-green);
  color: var(--color-white);
}

.btn--primary:hover,
.clickable-button:hover,
.btn-primary:hover,
.acc-row-btn--primary:hover,
form input[type='submit']:is(:hover, :focus-visible),
form .hs-button:is(:hover, :focus-visible),
.hs-search-field__button:is(:hover, :focus-visible) {
  background-color: var(--color-brand-green-dark);
  border-color: var(--color-brand-green-dark);
  color: var(--color-white);
}

.btn--secondary,
.clickable-button-secondary,
.btn-secondary,
.acc-row-btn--secondary,
.hs-button.hs-button--resend-sign-in,
.button-wrapper--secondary a {
  background-color: var(--color-white);
  border-color: var(--color-navy);
  color: var(--color-navy);
}

.btn--secondary:hover,
.clickable-button-secondary:hover,
.btn-secondary:hover,
.acc-row-btn--secondary:hover,
.hs-button.hs-button--resend-sign-in:is(:hover, :focus-visible),
.button-wrapper--secondary a:is(:hover, :focus-visible) {
  background-color: var(--color-bg-subtle);
  border-color: var(--color-navy);
  color: var(--color-navy);
}

.btn--danger,
.btn-danger {
  background-color: var(--color-danger);
  border-color: var(--color-danger);
  color: var(--color-white);
}

.btn--danger:hover,
.btn-danger:hover {
  background-color: var(--color-danger-dark);
  border-color: var(--color-danger-dark);
  color: var(--color-white);
}

/* After a click an anchor button stays focused: keep its own text colour. */
:is(
    .btn--primary,
    .clickable-button,
    .btn-primary,
    .acc-row-btn--primary,
    .btn--danger,
    .btn-danger
  ):focus {
  color: var(--color-white);
}

:is(
    .btn--secondary,
    .clickable-button-secondary,
    .btn-secondary,
    .acc-row-btn--secondary
  ):focus,
.button-wrapper--secondary a:focus {
  color: var(--color-navy);
}

/* HubSpot-generated buttons still get the theme's .button / .hs-button hover
   chrome (theme-overrides.css, D3), which swaps the border and radius: hold
   the shape through hover and keyboard focus. */
form input[type='submit']:is(:hover, :focus-visible),
form .hs-button:is(:hover, :focus-visible),
.button-wrapper--secondary a:is(:hover, :focus-visible) {
  border-width: 1px;
  border-style: solid;
  border-radius: var(--radius-button);
}

/* Text buttons: .btn--text keeps the 44px target; .button-link is the compact
   one that sits inline in toolbars and card footers. */
.btn--text {
  background: none;
  color: var(--color-brand-green);
  padding: 0 var(--space-1);
}

.button-link,
.disabled-button-link {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  min-height: var(--tap-target-min);
  padding: 0;
  font-size: var(--font-size-base);
  font-weight: var(--font-weight-semibold);
  text-align: left;
  cursor: pointer;
}

.button-link {
  color: var(--color-brand-green);
}

:is(.btn--text, .button-link):focus {
  color: var(--color-brand-green);
}

:is(.btn--text, .button-link):hover {
  color: var(--color-brand-green-dark);
  text-decoration: underline;
  text-underline-offset: 3px;
}

/* Disabled: one look for every variant (listed at 0-2-0 so it also beats the
   hover and colour rules above)
   ========================================================================== */

:is(
    .btn,
    .clickable-button,
    .clickable-button-secondary,
    .btn-primary,
    .btn-secondary,
    .btn-danger,
    .acc-row-btn
  ):is(:disabled, [aria-disabled='true']),
.disabled-button {
  background-color: var(--color-bg-subtle);
  border-color: var(--color-border);
  color: var(--color-placeholder);
  cursor: not-allowed;
}

.btn--text:is(:disabled, [aria-disabled='true']) {
  background: none;
  border-color: transparent;
}

:is(.btn--text, .button-link):is(:disabled, [aria-disabled='true']),
.disabled-button-link {
  color: var(--color-placeholder);
  text-decoration: none;
  cursor: not-allowed;
}

/* Text Link Styles
   Clean, minimal link for inline use (no bold, no hover change)
   ========================================================================== */

.text-link {
  color: var(--color-brand-green);
  text-decoration: underline;
  font-size: inherit;
}

.text-link:hover {
  color: var(--color-brand-green);
  text-decoration: underline;
}
/* ==========================================================================
   Form controls (ACC-2025 PR C: D5-D8, D14, D15; decisions in
   docs/style-audit.md section 5)

   One spec for every text field, select and textarea in the portal, inside a
   <form> or not. The element selectors sit at the lowest specificity (0,0,1)
   so a module class can still lay a field out; a module never restyles one
   (scripts/check-style-rules.js, rule R1).
     default   --control-height (44px, a button's height), 16px text so iOS
               never zooms, 12px radius, --color-border-input
     compact   .field--compact, --control-height-compact (36px), 14px text:
               filter bars above a list only
   ========================================================================== */

.hs-form-field {
  margin-bottom: var(--space-5);
  background-color: transparent;
}

/* Labels: one style (D6). A legend labels a checkbox or radio group, so it
   matches. Outside a <form> (Event Registration, the parent-info gate), the
   field's wrapper is .form-field (not .field: HubSpot's own form markup uses
   that). There a label that wraps its own checkbox or radio is an option, not
   the field's label, so it keeps its own look; the :where() keeps a browser
   without :has() from dropping the whole rule. */

form label,
form legend,
.form-field > legend,
.form-field > label:where(:not(:has(> input))) {
  display: block;
  margin-bottom: var(--space-1);
  font-size: var(--font-size-md);
  font-weight: var(--font-weight-semibold);
  line-height: 1.3;
  color: var(--color-text);
}

/* Form Title */
.form-title {
  margin-bottom: 0;
}

/* Field-level help and the "(optional)" label qualifier. Introduced by
   ACC-1858 for the optional child email; generic enough that any field can
   use them.

   Deliberately here rather than in a component file (raised in PR #176
   review): these are generic field annotations, not a component, and this
   file already carries class selectors for the same job — .hs-form-field,
   .form-title, .legal-consent-container — with the help-text rules directly
   above. A component file for two rules would split them from their siblings
   for no gain. */
.field-help {
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
  margin: var(--space-1) 0 0;
}

.optional-field {
  color: var(--color-text-secondary);
  font-weight: var(--font-weight-normal);
}

/* Required marker (D7): a red asterisk after the label text, never a red
   label. <span class="field-required">*</span> */
.field-required {
  color: var(--color-danger);
  margin-left: 2px;
}

/* Fields

   The text-like input types are listed three times below (the field, its
   focus and its disabled state). Keep the three lists in step; a test in
   tests/scripts/check-style-rules.test.js checks they match. */

input:where(
    :not([type]),
    [type='text'],
    [type='search'],
    [type='email'],
    [type='password'],
    [type='tel'],
    [type='number'],
    [type='url'],
    [type='date']
  ),
select,
textarea,
.custom-multi-display,
.acc-phone-dial-code {
  display: block;
  width: 100%;
  height: var(--control-height);
  padding: 0 14px;
  border: 1px solid var(--color-border-input);
  border-radius: var(--radius-lg);
  background-color: var(--color-white);
  color: var(--color-text);
  font-size: var(--font-size-base);
  transition: border-color 0.15s ease, box-shadow 0.15s ease;
}

/* The display above outranks the browser's [hidden] rule, so a hidden field
   needs its own (ACC_Region hides the province dropdown outside CA/US). */
:is(input, select, textarea)[hidden] {
  display: none;
}

textarea {
  height: auto;
  min-height: 104px;
  padding: 10px 14px;
  line-height: 1.5;
  resize: vertical;
}

input[readonly],
textarea[readonly] {
  border-color: var(--color-border);
  background-color: var(--color-bg-subtle);
}

/* Focus: the border turns brand green and a soft halo shows (D5). Fields
   show it for mouse focus too, since the caret goes there. */
input:where(
    :not([type]),
    [type='text'],
    [type='search'],
    [type='email'],
    [type='password'],
    [type='tel'],
    [type='number'],
    [type='url'],
    [type='date']
  ):focus,
select:focus,
textarea:focus,
.acc-phone-dial-code:focus,
#hs-subscriptions-other-option-input:focus /* outranks HubSpot's cyan ring */ {
  outline: none;
  border-color: var(--color-brand-green);
  box-shadow: var(--shadow-focus);
}

/* Disabled (a choice card whose input is disabled matches it, in
   components/_choice-card.css). */
input:where(
    :not([type]),
    [type='text'],
    [type='search'],
    [type='email'],
    [type='password'],
    [type='tel'],
    [type='number'],
    [type='url'],
    [type='date']
  ):disabled,
select:disabled,
textarea:disabled,
.acc-phone-dial-code:disabled {
  border-color: var(--color-border);
  background-color: var(--color-bg-subtle);
  color: var(--color-text-muted);
  cursor: not-allowed;
}

/* Select (D14): the native control with our chevron (--icon-select-chevron),
   inset from the edge. */
select {
  appearance: none;
  padding-right: 44px;
  background-image: var(--icon-select-chevron);
  background-position: right 14px center;
  background-repeat: no-repeat;
  background-size: 16px;
  cursor: pointer;
}

select[multiple] {
  height: auto;
  padding: var(--space-1);
  background-image: none;
}

/* Where the browser supports it (Chrome and Edge 135+), the open list is
   themed too: rounded, brand hover, a check on the chosen option. Safari,
   Firefox and phones keep their native list. The chevron stays the
   background image rather than the picker icon: a long choice in a narrow
   field then clips short of it instead of wrapping onto a second line (the
   picker icon would be pushed out of the field). Clipping at the content box,
   not the padding box, keeps the text out from under the chevron. */
@supports (appearance: base-select) {
  select:where(:not([multiple])),
  select:where(:not([multiple]))::picker(select) {
    appearance: base-select;
  }

  select:where(:not([multiple])) {
    display: flex;
    align-items: center;
    overflow: clip;
    overflow-clip-margin: content-box;
    white-space: nowrap;
  }

  select:where(:not([multiple]))::picker-icon {
    display: none;
  }

  select:where(:not([multiple]))::picker(select) {
    margin-block: 6px;
    padding: 6px;
    border: 1px solid var(--color-border);
    border-radius: var(--radius-lg);
    background-color: var(--color-white);
    box-shadow: var(--shadow-md);
  }

  select:where(:not([multiple])) option {
    gap: 10px;
    padding: 10px var(--space-3);
    border-radius: var(--radius-md);
    color: var(--color-text);
    font-size: var(--font-size-base);
  }

  select:where(:not([multiple])) option:is(:hover, :focus-visible) {
    outline: none;
    background-color: var(--color-brand-tint);
  }

  select:where(:not([multiple])) option:checked {
    color: var(--color-brand-green-dark);
    font-weight: var(--font-weight-semibold);
  }

  select:where(:not([multiple])) option::checkmark {
    color: var(--color-brand-green);
  }

  select.field--compact option {
    padding: var(--space-2) 10px;
    font-size: var(--font-size-md);
  }
}

/* Date (D15): the native field, left-aligned, with a quieter calendar icon.
   Phones open their own date picker. */
input[type='date']::-webkit-calendar-picker-indicator {
  opacity: 0.7;
  cursor: pointer;
}

/* iOS Safari centres the value otherwise. */
input[type='date']::-webkit-date-and-time-value {
  text-align: left;
}

/* Compact: filter bars above a list. */
.field--compact {
  height: var(--control-height-compact);
  padding: 0 10px;
  border-radius: var(--radius-md);
  font-size: var(--font-size-md);
}

select.field--compact {
  padding-right: 34px;
  background-position: right 10px center;
}

/* A filter that is narrowing the list. */
.field--compact.active {
  border-color: var(--color-brand-green);
  background-color: var(--color-brand-tint);
}

/* Room for an icon inside the field (e.g. a search magnifier on the left, a
   clear button on the right). The icon itself is positioned by its module. */
.field--icon-start {
  padding-left: var(--space-10);
}

.field--icon-end {
  padding-right: var(--space-10);
}

form fieldset {
  max-width: 100% !important;
}

/* Placeholder: muted, so an empty field never reads as filled. The theme
   setting used here before matched the typed-text colour (ACC-2025). */
::placeholder {
  color: var(--color-text-muted);
  opacity: 1;
}

/* Checkboxes and radios (D8): native, 20px, brand green. */

input:where([type='checkbox'], [type='radio']) {
  flex-shrink: 0;
  width: 20px;
  height: 20px;
  accent-color: var(--color-brand-green);
  cursor: pointer;
}

form .inputs-list {
  margin: 0;
  padding: 0;
  list-style: none;
}

form .inputs-list > li {
  display: block;
  margin: var(--space-3) 0;
}

form .inputs-list input,
form .inputs-list span {
  vertical-align: middle;
}

form input[type=checkbox],
form input[type=radio] {
  margin-right: var(--space-1);
}

/* Inputs - date picker */

.hs-dateinput {
  position: relative;
}

.hs-dateinput:before {
  content:'\01F4C5';
  position: absolute;
  right: 10%;
  top: 50%;
  transform: translateY(-50%);
}

.fn-date-picker .pika-table thead th {
  color: var(--color-white);
}

.fn-date-picker td.is-selected .pika-button {
  border-radius: 0;
  box-shadow: none;
}

.fn-date-picker td .pika-button:hover,
.fn-date-picker td .pika-button:focus {
  border-radius: 0 !important;
  color: var(--color-white);
}

/* Headings and text */

form .hs-richtext,
form .hs-richtext p {
  font-size: var(--font-size-md);
  margin: 0 0 1.4rem;
}

form .hs-richtext img {
  max-width: 100% !important;
}

/* GDPR */

.legal-consent-container .hs-form-booleancheckbox-display > span,
.legal-consent-container .hs-form-booleancheckbox-display > span p {
  margin-left: 1rem !important;
}

/* Validation: HubSpot-rendered forms (login, password reset, subscription
   preferences) take the one error red (D7). HubSpot's own membership CSS
   draws a 2px pink border with !important, so the override needs the extra
   element in its selector. */

.hs-form-required {
  color: var(--color-danger);
}

.hs-input.invalid.error,
input.form-input-error {
  border: 1px solid var(--color-danger) !important;
}

.hs-error-msg {
  color: var(--color-danger);
  margin-top: 0;
}

form .form-input-validation-message-error label {
  color: var(--color-danger);
}

/* Submit button: HubSpot form submits (login, password reset, subscription
   preferences) take the primary button look from elements/_buttons.css. */

form input[type=submit],
form .hs-button {
  min-width: 200px;
  white-space: normal;
}

/* Captcha */

.grecaptcha-badge {
  margin: 0 auto;
}


  /* Search button input field and suggestions */
  /* Card wrapper + attached input/button pill (mirrors the help-centre search) */
  .body-container-wrapper .hs-search-field {
    background: var(--color-white);
    border: 1px solid var(--color-bg-muted);
    border-radius: var(--radius-lg);
    padding: var(--space-3);
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.04);
  }

  .body-container-wrapper .hs-search-field__bar > form {
    display: flex;
    align-items: stretch;
    background: transparent;
  }

  /* Attached to the input: square seam on the left, rounded outer corner on the right. */
  .body-container-wrapper .hs-search-field__bar--button-inline .hs-search-field__button {
    margin-left: 0;
    margin-bottom: 0;
    border-radius: 0 var(--radius-md) var(--radius-md) 0;
  }

  .body-container-wrapper .hs-search-field__button svg {
    height: 15px;
    fill: var(--color-white);
  }

  /* Grows to fill the bar; rounded outer corner on the left, square seam on the right. */
  .body-container-wrapper .hs-search-field__bar > form > .hs-search-field__input {
    flex: 1;
    padding: 10px 14px;
    border: 1px solid var(--color-border-strong);
    border-right: none;
    border-radius: var(--radius-md) 0 0 var(--radius-md);
  }

  .body-container-wrapper .hs-search-field__suggestions li a {
    color: var(--color-text-secondary);
    padding: 0.35rem 0.7rem;
    text-decoration: none;
    transition: background-color 0.3s;
  }


/* Inline field-error span, written by the module JS validate helpers next to
   the field it belongs to (id convention <inputId>-error). Here rather than in
   a component file for the same reason as .field-help above: a generic field
   annotation, not a component, and it pairs with the .invalid-highlight rule
   below. Previously carried as byte-identical copies in Update Personal
   Information's and Custom Registration's module.css. */
.custom-error {
  display: none;
  color: var(--color-danger);
  font-size: var(--font-size-sm);
  margin-top: var(--space-1);
}

/* Validation highlight (D7): one red border, and the message under the
   field. Module JS validate helpers add .invalid-highlight to any required
   field that fails checkValidity (inputs, selects and textareas alike); Custom
   Registration and Update Personal Information also mark the form
   .was-validated on a submit attempt, which lights every required field still
   empty. Checks run on blur or submit, never on focus. It comes after the
   focus rule above, which it ties with, so it wins; module CSS may no longer
   restyle a field's border (style guardrail R1). */
input.invalid-highlight,
select.invalid-highlight,
textarea.invalid-highlight,
.acc-phone-dial-code.invalid-highlight,
form.was-validated :is(input, select, textarea):required:invalid {
  border-color: var(--color-danger);
}

input.invalid-highlight:focus,
select.invalid-highlight:focus,
textarea.invalid-highlight:focus,
.acc-phone-dial-code.invalid-highlight:focus,
form.was-validated :is(input, select, textarea):required:invalid:focus {
  box-shadow: var(--shadow-focus-danger);
}

/* A checkbox/radio group (a fieldset) has no border to colour, so its legend
   carries the highlight instead. */
fieldset.invalid-highlight legend {
  color: var(--color-danger);
}
/* Table */

table {
  border-collapse: collapse;
  margin-bottom: 1.4rem;
  overflow-wrap: break-word;
}

/* Table cells */

td,
th {
  vertical-align: top;
}

/* Table header */

thead th {
  vertical-align: bottom;
}

/* Components
Specific pieces of UI that are stylized. Typically used for global partial styling
Note: Header styles are in Portal Header.module/module.css (kept with the module);
the shared EN/FR language switcher lives in _language-switcher.css below.
*/

/* Menu and simple menu */

.hs-menu-wrapper ul {
  display: flex;
  flex-wrap: wrap;
  list-style: none;
  margin: 0;
  padding-left: 0;
}

/* Horizontal menu */

.hs-menu-wrapper.hs-menu-flow-horizontal .hs-menu-children-wrapper {
  flex-direction: column;
}

@media (max-width: 767px) {
  .hs-menu-wrapper.hs-menu-flow-horizontal ul {
    flex-direction: column;
  }
}

/* Vertical menu */

.hs-menu-wrapper.hs-menu-flow-vertical ul {
  flex-direction: column;
}

/* Flyouts */

.hs-menu-wrapper.hs-menu-flow-vertical.flyouts ul {
  display: inline-flex;
}

@media (max-width: 767px) {
  .hs-menu-wrapper.hs-menu-flow-vertical ul {
    display: flex;
  }
}

.hs-menu-wrapper.flyouts .hs-item-has-children {
  position: relative;
}

.hs-menu-wrapper.flyouts .hs-menu-children-wrapper {
  left: -9999px;
  opacity: 0;
  position: absolute;
}

.hs-menu-wrapper.flyouts .hs-menu-children-wrapper a {
  display: block;
  white-space: nowrap;
}

.hs-menu-wrapper.hs-menu-flow-horizontal.flyouts
  .hs-item-has-children:hover
  > .hs-menu-children-wrapper {
  left: 0;
  opacity: 1;
  top: 100%;
}

.hs-menu-wrapper.hs-menu-flow-vertical.flyouts
  .hs-item-has-children:hover
  > .hs-menu-children-wrapper {
  left: 100%;
  opacity: 1;
  top: 0;
}

@media (max-width: 767px) {
  .hs-menu-wrapper.flyouts .hs-menu-children-wrapper,
  .hs-menu-wrapper.hs-menu-flow-horizontal.flyouts
    .hs-item-has-children:hover
    > .hs-menu-children-wrapper,
  .hs-menu-wrapper.hs-menu-flow-vertical.flyouts
    .hs-item-has-children:hover
    > .hs-menu-children-wrapper {
    left: 0;
    opacity: 1;
    position: relative;
    top: auto;
  }
}

/* CTA, logo, and rich text images */

.hs_cos_wrapper_type_cta img,
.hs_cos_wrapper_type_logo img,
.hs_cos_wrapper_type_rich_text img {
  height: auto;
  max-width: 100%;
}
/* Snackbar notification styles */

.snackbar {
  visibility: hidden;
  min-width: 300px;
  max-width: 500px;
  background-color: var(--color-danger);
  color: var(--color-white);
  /*text-align: left;*/
  padding: var(--space-4);
  padding-right: 40px;
  border-radius: var(--radius-sm);
  position: fixed;
  left: 50%;
  bottom: 30px;
  transform: translateX(-50%);
  font-size: var(--font-size-md);
  /* --z-toast, not --z-modal: the snackbar must clear the record sheet's
     overlay, which also sits at --z-modal. On a tie the later import wins
     (_record-sheet.css is included after this file in main.css), so a
     success toast fired from inside the sheet rendered UNDERNEATH it. */
  z-index: var(--z-toast);
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.3);
  transition: visibility 0s, opacity 0.5s ease;
  opacity: 0;
}

/* Success variant - green */
.snackbar.success {
  background-color: var(--color-success);
}

/* Warning variant - orange/amber */
.snackbar.warning {
  background-color: var(--color-warning);
}

/* Multi-warning messages (e.g. /registration spouse + child email collisions,
   ACC-1967) arrive as one string with \n separators — render them as lines. */
.snackbar .snackbar-message {
  white-space: pre-line;
}

/* Error variant - red (default) */
.snackbar.error {
  background-color: var(--color-danger);
}

/* Info variant - blue */
.snackbar.info {
  background-color: var(--color-info);
}

/* Show animation */
.snackbar.show {
  visibility: visible;
  opacity: 1;
}

/* Snackbar close button - positioned top right */
.snackbar-close {
  position: absolute;
  top: 0px;
  right: 8px;
  color: var(--color-white);
  font-size: var(--font-size-xl);
  font-weight: var(--font-weight-bold);
}

/* White (the icon colour): brand green would vanish on the success snackbar.
   Scoped to outrank the global focus ring in elements/_buttons.css (0-2-1). */
.snackbar .snackbar-close:focus-visible {
  outline: 2px solid currentColor;
  outline-offset: 2px;
}
/* ==========================================================================
   Info Box Component
   Reusable information callout boxes for displaying messages to users
   ========================================================================== */

/* Base Info Box
   ========================================================================== */

.info-box {
  background-color: var(--color-info-bg);
  border: 1px solid var(--color-info);
  border-radius: var(--radius-lg);
  padding: var(--space-5);
  display: flex;
  margin-bottom: 20px;
  align-items: flex-start;
  gap: 15px;
}

/* `display: flex` above outranks the UA's [hidden] { display: none }, so a
   box toggled with the hidden attribute stayed visible (Fair Access
   Bookings' pending / error / fallback boxes). Event Registration already
   carries a module-scoped `[hidden]` guard; this covers every other user of
   the component without one. */
.info-box[hidden] {
  display: none;
}

.info-box .info-box-icon {
  flex-shrink: 0;
}

.info-box .info-box-icon i {
  font-size: var(--font-size-3xl);
  color: var(--color-info);
}

.info-box .info-box-content {
  flex: 1;
}

.info-box-content p {
  margin: 0;
  color: var(--color-info-text);
  font-size: var(--font-size-md);
  line-height: 1.6;
}

.info-box-content p + p {
  margin-top: 8px;
}

.info-box-content a {
  color: var(--color-info);
  font-weight: var(--font-weight-semibold);
  text-decoration: none;
}

.info-box-content a:hover {
  text-decoration: underline;
}

.info-box-content strong {
  font-weight: var(--font-weight-semibold);
}

/* Info Box Variants
   ========================================================================== */

/* Warning variant - orange/yellow */
.info-box.info-box--warning {
  background-color: var(--color-warning-bg);
  border-color: var(--color-warning);
}

.info-box.info-box--warning .info-box-icon i {
  color: var(--color-warning);
}

.info-box.info-box--warning .info-box-content p {
  color: var(--color-warning-text);
}

/* Success variant - green */
.info-box.info-box--success {
  background-color: var(--color-success-bg);
  border-color: var(--color-brand-green);
}

.info-box.info-box--success .info-box-icon i {
  color: var(--color-brand-green);
}

.info-box.info-box--success .info-box-content p {
  color: var(--color-brand-green-dark);
}

/* Error variant - red */
.info-box.info-box--error {
  background-color: var(--color-danger-bg);
  border-color: var(--color-danger);
}

.info-box.info-box--error .info-box-icon i {
  color: var(--color-danger);
}

.info-box.info-box--error .info-box-content p {
  color: var(--color-danger-text);
}

/* Registration Info Box
   Specific styling for event registration user info
   ========================================================================== */

.registration-info-box {
  margin-bottom: 25px;
}

.registration-info-box .info-box-content .user-name {
  font-weight: var(--font-weight-semibold);
  font-size: var(--font-size-base);
}

.registration-info-box .info-box-content .user-email {
  color: var(--color-info);
}

/* Already Registered Modal
   Modal displayed when user is already registered for an event
   ========================================================================== */

.already-registered-modal {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background-color: rgba(0, 0, 0, 0.5);
  display: flex;
  justify-content: center;
  align-items: center;
  z-index: var(--z-modal);
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.3s ease, visibility 0.3s ease;
}

.already-registered-modal.active {
  opacity: 1;
  visibility: visible;
}

.already-registered-modal .modal-content {
  background-color: var(--color-white);
  border-radius: var(--radius-lg);
  padding: 30px;
  max-width: 500px;
  width: 90%;
  box-shadow: var(--shadow-md);
  text-align: center;
}

.already-registered-modal .modal-icon {
  margin-bottom: 20px;
}

.already-registered-modal .modal-icon i {
  font-size: 48px;
  color: var(--color-warning);
}

.already-registered-modal .modal-content h3 {
  margin: 0 0 15px 0;
  font-size: var(--font-size-2xl);
  color: var(--color-text);
}

.already-registered-modal .modal-content p {
  margin: 0 0 25px 0;
  color: var(--color-text-secondary);
  font-size: var(--font-size-md);
  line-height: 1.6;
}

.already-registered-modal .modal-buttons {
  display: flex;
  gap: 15px;
  justify-content: center;
  flex-wrap: wrap;
}

/* Why a control is off (ACC-2025, D16): a visible note under the buttons,
   not a hover-only tooltip that phones and keyboard users never see.
   ========================================================================== */

.disabled-reason {
  display: flex;
  gap: var(--space-2);
  align-items: flex-start;
  /* As wide as its text, so it reads as a note on the control above it. */
  width: fit-content;
  margin: var(--space-2) 0 0;
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-md);
  background: var(--color-bg-subtle);
  color: var(--color-text-body);
  font-size: var(--font-size-md);
  line-height: 1.4;
  text-align: left;
}

.disabled-reason i {
  margin-top: 2px;
  color: var(--color-navy);
}

/* Where the button rows stack and go full width, so does the note. */
@media (max-width: 768px) {
  .disabled-reason {
    width: auto;
  }
}

/* Mobile Responsive
   ========================================================================== */

@media only screen and (max-width: 600px) {
  .info-box {
    flex-direction: column;
    align-items: center;
    text-align: center;
    padding: 15px;
  }

  .info-box .info-box-icon {
    margin-bottom: 10px;
  }

  .already-registered-modal .modal-content {
    padding: var(--space-5);
    margin: 15px;
  }

  .already-registered-modal .modal-buttons {
    flex-direction: column;
  }

  .already-registered-modal .modal-buttons button {
    width: 100%;
  }
}
/* ==========================================================================
   Pagination Component
   Shared pagination controls used across multiple modules.
   Uses !important to ensure styles work when modules are embedded
   across different HubSpot themes.

   The .hs-search-results__pagination* selectors map the same look onto the
   stock @hubspot/search_results module on the /search page, whose pagination
   markup is generated client-side and cannot be edited:

     <nav class="hs-search-results__pagination">
       <a class="...__link ...__link--text-and-icon ...__link--first [--disabled]">« First Page</a>
       <a class="...__link ...__link--number [...__link--active]">1</a>
       <span class="...__link">…</span>
       <a class="...__link ...__link--text-and-icon ...__link--last">Last Page »</a>
     </nav>

   The !important flags also override the stock module's own stylesheet here.
   ========================================================================== */

.pagination-controls,
.hs-search-results__pagination {
  display: flex !important;
  flex-wrap: wrap !important; /* wrap instead of overflowing on narrow screens */
  justify-content: center !important;
  align-items: center !important;
  gap: 10px !important;
  margin: var(--space-10) 0 var(--space-5) !important;
  padding: var(--space-5) !important;
}

.pagination-controls.hidden {
  display: none !important;
}

.pagination-btn,
.hs-search-results__pagination__link--text-and-icon {
  padding: var(--space-2) var(--space-4) !important;
  background: var(--color-white) !important;
  border: 1px solid var(--color-border) !important;
  border-radius: var(--radius-sm) !important;
  cursor: pointer !important;
  font-size: var(--font-size-md) !important;
  transition: all 0.2s !important;
  color: var(--color-text) !important;
  text-decoration: none !important;
}

.pagination-btn:hover:not(:disabled),
.hs-search-results__pagination__link--text-and-icon:hover {
  background: var(--color-brand-green) !important;
  color: var(--color-white) !important;
  border-color: var(--color-brand-green) !important;
}

.pagination-btn:disabled {
  opacity: 0.5 !important;
  cursor: not-allowed !important;
}

.page-numbers {
  display: flex !important;
  gap: 5px !important;
}

.page-number,
.hs-search-results__pagination__link--number {
  padding: var(--space-2) var(--space-3) !important;
  background: var(--color-white) !important;
  border: 1px solid var(--color-border) !important;
  border-radius: var(--radius-sm) !important;
  cursor: pointer !important;
  font-size: var(--font-size-md) !important;
  transition: all 0.2s !important;
  color: var(--color-text) !important;
  min-width: 40px !important;
  text-align: center !important;
  text-decoration: none !important;
  /* Search number links are flex items (stock sets display: flex); inert on the button. */
  justify-content: center !important;
}

.page-number:hover,
.hs-search-results__pagination__link--number:hover {
  background: var(--color-brand-green) !important;
  color: var(--color-white) !important;
  border-color: var(--color-brand-green) !important;
}

.page-number.active,
.hs-search-results__pagination__link--active {
  background: var(--color-brand-green) !important;
  color: var(--color-white) !important;
  border-color: var(--color-brand-green) !important;
  font-weight: var(--font-weight-semibold) !important;
}

.pagination-info {
  font-size: var(--font-size-md) !important;
  color: var(--color-text-secondary) !important;
  padding: var(--space-2) var(--space-4) !important;
}

/* Search-results-only adjustments to the stock module's markup. */

/* The stock stylesheet spaces links with margins; the flex gap above replaces them. */
.hs-search-results__pagination__link {
  margin: 0 !important;
}

/* The stock module computes ONE shared disabled flag, so on the first and last
   pages it stamps --disabled on ALL FOUR first/prev/next/last links (stock
   bug). Ignore that class and derive the real state instead: first/prev are
   inert when the active page number is the first number shown, next/last when
   it is the last (truncation always keeps the first and last numbers visible).
   The links keep a real href, so without pointer-events they would still
   trigger a pointless reload of the current page. */
.hs-search-results__pagination:has(
    .hs-search-results__pagination__link--active
  ):not(
    :has(
        .hs-search-results__pagination__link--number
          ~ .hs-search-results__pagination__link--active
      )
  )
  :is(
    .hs-search-results__pagination__link--first,
    .hs-search-results__pagination__link--prev
  ),
.hs-search-results__pagination:has(
    .hs-search-results__pagination__link--active
  ):not(
    :has(
        .hs-search-results__pagination__link--active
          ~ .hs-search-results__pagination__link--number
      )
  )
  :is(
    .hs-search-results__pagination__link--next,
    .hs-search-results__pagination__link--last
  ) {
  opacity: 0.5 !important;
  pointer-events: none !important;
}

/* The shared pagination buttons are text-only (cf. the events page); hide the
   stock arrow icons. */
.hs-search-results__pagination__link-icon {
  display: none !important;
}

/* Truncation ellipsis between page numbers renders as a bare span. */
span.hs-search-results__pagination__link {
  color: var(--color-text-secondary) !important;
  font-size: var(--font-size-md) !important;
}

/* On narrow phones the full First/Prev/1 2 3/Next/Last row overflows. Drop the
   page numbers and tighten spacing so First/Prev/Next/Last stay on one line.
   The stock search nav already wraps (flex-wrap above), so scope this to our
   own .pagination-controls. */
@media (max-width: 480px) {
  .pagination-controls {
    gap: var(--space-2) !important;
    padding: var(--space-3) !important;
  }

  .pagination-controls .page-numbers {
    display: none !important;
  }
}
/* ==========================================================================
   Shared Table Styles
   Base styles for all table-like layouts (HTML tables and flex-based tables).
   ========================================================================== */

/* List tables (My Registrations, My Hut Bookings, Staffed Trips, Transactions)
   and the bordered HTML table below share one look (ACC-1946, ACC-2056): a
   rounded outline, a grey header band with dividers, and calm rows. Column
   widths and the card layout below 1024px stay with each module.
   ========================================================================== */

.flex-table,
.table-wrapper {
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
}

.flex-table {
  overflow: hidden;
}

/* Header and rows are separate flex containers; columns line up only while
   both have the same content box. */
.flex-table-head ul,
.flex-table-body ul {
  display: flex;
  list-style: none;
  margin: 0;
  padding: 0;
}

.flex-table-head ul > li,
.flex-table-body ul > li,
.table-wrapper .data-table th,
.table-wrapper .data-table td {
  padding: var(--space-4) var(--space-3);
}

/* Cells grow to take up the slack between columns, in the header and the body
   alike: each header divider then sits on its column's edge. */
.flex-table-head ul > li,
.flex-table-body ul > li {
  flex-grow: 1;
}

.flex-table-head ul {
  /* Stretch, so the dividers run the full height of the band. */
  align-items: stretch;
  background: var(--color-bg-page);
  border-bottom: 2px solid var(--color-border);
}

.flex-table-head ul > li,
.table-wrapper .data-table th {
  border-right: 1px solid var(--color-border);
  font-size: var(--font-size-xs);
  text-transform: uppercase;
  letter-spacing: 0.3px;
}

.flex-table-head ul > li:last-child,
.table-wrapper .data-table th:last-child {
  border-right: none;
}

.flex-table-head ul > li {
  display: flex;
  align-items: center;
  font-weight: var(--font-weight-semibold);
  color: var(--color-navy);
}

.flex-table-body ul {
  /* Wraps, so a full-width panel inside a row drops under its cells. */
  flex-wrap: wrap;
  align-content: center;
  align-items: center;
  background: var(--color-white);
  position: relative;
  transition: background 0.15s ease;
}

.flex-table-body ul:hover {
  background: var(--color-brand-tint);
}

/* A light rule between rows. My Hut Bookings draws its own, on the group that
   wraps each row. */
.flex-table-body ul ~ ul {
  border-top: 1px solid var(--color-bg-muted);
}

.flex-table-body ul > li {
  font-size: var(--font-size-md);
}

/* Below this width each module turns its rows into cards and hides the
   header, so the list has no box of its own (and must not clip the cards'
   shadows). */
@media only screen and (max-width: 1024px) {
  .flex-table {
    overflow: visible;
    border: none;
  }
}

/* HTML table base styles (used by line-items, gantt, results, section admin)
   ========================================================================== */

.data-table {
  width: 100%;
  border-collapse: collapse;
  font-variant-numeric: tabular-nums;
}

.data-table th {
  text-align: left;
  padding: 10px var(--space-3);
  font-weight: var(--font-weight-semibold);
  color: var(--color-navy);
  font-size: var(--font-size-sm);
  background: var(--color-bg-page);
  border-bottom: 2px solid var(--color-border);
}

.data-table td {
  padding: 10px var(--space-3);
  border-bottom: 1px solid var(--color-bg-muted);
}

.data-table tbody tr:last-child td {
  border-bottom: none;
}

.data-table tbody tr {
  transition: background 0.15s ease;
}

.data-table tbody tr:hover {
  background: var(--color-brand-tint);
}

/* Numeric alignment — apply to amount/quantity columns */
.data-table .col-numeric {
  text-align: right;
  font-variant-numeric: tabular-nums;
}

/* Bordered HTML table (Section Admin). Scoped to the wrapper so other
   .data-table users keep their own look.
   ========================================================================== */

/* The wrapper's overflow already clips, so the radius rounds the outer edge
   and trims the table's square corners — do NOT switch this to
   `overflow: hidden` to force clipping, that would kill the horizontal scroll
   a wide table needs. */
.table-wrapper {
  overflow-x: auto;
}

/* No margin: the global `table` rule's 1.4rem showed as an empty band under
   the last row inside the outline. No border: the theme's border shorthand on
   `table` would draw a square outline inside the wrapper's rounded corners. */
.table-wrapper .data-table {
  margin-bottom: 0;
  border: none;
}

/* Cell borders follow the HubSpot CRM table pattern: dividers between HEADER
   cells, none in the body, light horizontal rules between body rows.

   Every side has to be named, because the theme applies a `border` SHORTHAND to
   every td/th (theme.tables.cells.border) — leave a side undeclared and its dark
   1px shows there. A blanket `border: none` isn't the answer either: it would
   take the horizontal row rule with it. */
.table-wrapper .data-table th,
.table-wrapper .data-table td {
  /* Middle so a wrapped value doesn't leave its neighbours hanging. */
  vertical-align: middle;
  border-left: none;
}

/* Under border-collapse this top border and .data-table's identical
   `border-bottom` describe the same line, and only one paints it. Declaring
   this one means the rule is the light token whichever side wins the
   tie-break. */
.table-wrapper .data-table td {
  border-right: none;
  border-top: 1px solid var(--color-bg-muted);
  color: var(--color-text-body);
}

/* `border-top: none` because the wrapper already draws the table's outer edge —
   left undeclared, the theme's dark 1px lands a second line right on top of it.
   (Left comes from the rule above, bottom from .data-table th.) */
.table-wrapper .data-table th {
  white-space: nowrap;
  border-top: none;
}

@media (max-width: 768px) {
  .table-wrapper .data-table th,
  .table-wrapper .data-table td {
    padding: var(--space-3) var(--space-2);
  }
}

/* Nested table variant (e.g. line items inside a record sheet)
   Lighter styling to sit within a panel background
   ========================================================================== */

.data-table--nested {
  margin-top: 8px;
  margin-bottom: 0;
  font-size: var(--font-size-md);
  border-collapse: separate;
  border-spacing: 0;
  border: none;
  border-radius: var(--radius-md);
  overflow: hidden;
}

.data-table--nested th {
  background: transparent;
  border: none;
  border-bottom: 1px solid var(--color-border);
  font-size: var(--font-size-xs);
  color: var(--color-text-secondary);
  padding: var(--space-2) var(--space-3);
}

.data-table--nested td {
  padding: var(--space-2) var(--space-3);
  border: none;
  border-bottom: 1px solid var(--color-bg-muted);
}

.data-table--nested tbody tr:last-child td {
  border-bottom: none;
}
/* ==========================================================================
   Toggle Component
   Shared toggle/tab button controls used across multiple modules
   ========================================================================== */

.toggle-group {
  display: flex;
  gap: 0;
  margin-bottom: var(--space-4);
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-md);
  overflow: hidden;
  width: fit-content;
}

.toggle-btn {
  background: var(--color-white);
  color: var(--color-text);
  display: flex;
  align-items: center;
  font-size: var(--font-size-md);
  gap: var(--space-2);
  padding: var(--space-2) var(--space-4);
}

.toggle-btn:not(:last-child) {
  border-right: 1px solid var(--color-border-strong);
}

.toggle-btn--active {
  background: var(--color-brand-green);
  color: var(--color-white);
}

@media only screen and (max-width: 768px) {
  .toggle-group {
    width: 100%;
  }

  .toggle-btn {
    flex: 1;
    justify-content: center;
    text-align: center;
  }
}
/* ==========================================================================
   Status Pill Component
   Shared status indicator chips used across multiple modules
   ========================================================================== */

.status-pill {
  display: inline-block;
  padding: var(--space-1) 10px;
  border-radius: var(--radius-pill);
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-semibold);
  text-transform: uppercase;
  letter-spacing: 0.5px;
}

.success-pill {
  background-color: var(--color-success-bg);
  color: var(--color-success-text);
  border: 1px solid var(--color-success);
}

.danger-pill {
  background-color: var(--color-danger-bg);
  color: var(--color-danger-text);
  border: 1px solid var(--color-danger);
}

.refund-pill {
  background-color: var(--color-bg-muted);
  color: var(--color-text);
  border: 1px solid var(--color-text-muted);
}

.warning-pill {
  background-color: var(--color-warning-bg);
  color: var(--color-warning-text);
  border: 1px solid var(--color-warning);
}

.info-pill {
  background-color: var(--color-info-bg);
  color: var(--color-info-text);
  border: 1px solid var(--color-info-cyan);
}

/* Informational-only state (e.g. a non-member hut-booking spot) — softer
   than .refund-pill, never an alarm colour. */
.muted-pill {
  background-color: var(--color-bg-subtle);
  color: var(--color-text-secondary);
  border: 1px solid var(--color-border);
}

/* Verification (ACC-1708)
   ==========================================================================
   One status chip saying where a booking stands, with the specific items
   listed under it. Reports outstanding WORK, unlike the lifecycle pills above
   which report a state — hence the sentence case and leading glyph, so the
   two kinds never read alike even side by side.

   The severities are deliberately not the same three as the lifecycle pills:
   red is reserved for work the OWNER can finish, and amber for work that
   belongs to someone else (a guest buying their own membership). Nagging in
   red about something the owner cannot complete is the thing this split
   exists to avoid. */
.v-status {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: var(--space-1) 10px;
  border-radius: var(--radius-pill);
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-semibold);
  white-space: nowrap;
}

/* Owner has something to do — the only blocking state. */
.v-status--action {
  background-color: var(--color-danger-bg);
  color: var(--color-danger-text);
  border: 1px solid var(--color-danger);
}

/* Waiting on a guest; not the owner's to complete. */
.v-status--pending {
  background-color: var(--color-warning-bg);
  color: var(--color-warning-text);
  border: 1px solid var(--color-warning);
}

.v-status--ok {
  background-color: var(--color-success-bg);
  color: var(--color-success-text);
  border: 1px solid var(--color-success);
}

/* Not a verdict — a role (someone else owns this booking) or something
   optional left undone. Informational tone so it sits in the family without
   reading as a state to resolve. */
.v-status--guest,
.v-status--optional {
  background-color: var(--color-info-bg);
  color: var(--color-info-text);
  border: 1px solid var(--color-info-cyan);
}

/* The glyph is decoration, not the message — every chip states its status in
   words, so colour and icon are never the sole carrier. */
.v-status > i {
  font-size: 0.85em;
}

/* The items themselves, under the chip. */
.v-issues {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 2px;
  margin-top: 6px;
}

.v-issue {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  font-size: var(--font-size-xs);
  color: var(--color-warning-text);
  text-align: left;
  text-decoration: underline;
  text-underline-offset: 2px;
}

.v-issue > i {
  font-size: 0.9em;
  flex-shrink: 0;
}

/* Not the owner's to fix, so it reads as information: no underline, no
   pointer — looking clickable would promise an action the sheet can't offer. */
.v-issue--pending {
  color: var(--color-text-secondary);
  text-decoration: none;
  cursor: default;
}

/* Optional work. Clickable — the owner CAN fill these — but never amber:
   it informs without demanding, so an unfilled non-member spot is accounted
   for rather than silently absent. */
.v-issue--info {
  color: var(--color-text-muted);
  /* Clickable, but a count, not a task — no underline, same as the other
     non-task lines. The earlier omission of this was the stray underline. */
  text-decoration: none;
}

.v-issue--info:hover,
.v-issue--info:focus {
  color: var(--color-text-muted);
}

/* Already done. Listed rather than dropped so the owner can see the whole of
   what "validating this booking" means, not just the parts still outstanding. */
.v-issue--done {
  color: var(--color-text-muted);
  text-decoration: none;
  cursor: default;
}

.v-issue--done > i {
  color: var(--color-success);
}

/* The row's one-line summary under its chip ("2 of 3 done"). One line
   means one line: the table column must widen rather than break the
   phrase ("managed by the / owner"); below 1024px the rows are stacked
   cards with room to spare. */
.v-summary {
  display: block;
  margin-top: 4px;
  font-size: var(--font-size-xs);
  color: var(--color-text-muted);
  white-space: nowrap;
}

/* In the sheet the checklist has room: normal text size, breathing room
   between lines. */
.v-issues--sheet {
  gap: 6px;
  margin-top: var(--space-2);
}

.v-issues--sheet .v-issue {
  font-size: var(--font-size-sm);
}

/* Required / Optional headings inside the cell. */
.v-section-label {
  margin-top: var(--space-1);
  font-size: var(--font-size-2xs);
  font-weight: var(--font-weight-bold);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--color-text-muted);
}

.v-section-label:first-child {
  margin-top: 0;
}

/* Nothing outstanding because the trip is over. */
.verification-none {
  color: var(--color-text-muted);
  font-size: var(--font-size-xs);
}
/* ==========================================================================
   Chips (ACC-2072)
   A row of short read-only values, e.g. a member's interests.

   <ul class="chip-list">
     <li class="chip">Hiking</li>
   </ul>

   For a set where every option is listed and some are chosen, each chip is
   .chip--on or .chip--off. On repeats a chosen choice card (brand border and
   tint) and carries a check icon, so colour is never the only signal; off is
   muted. Each one also says its state in a .show-for-sr span.
   Statuses are .status-pill, not chips.
   ========================================================================== */

.chip-list {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  margin: var(--space-2) 0 0;
  padding: 0;
  list-style: none;
}

.chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin: 0;
  padding: var(--space-1) var(--space-3);
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-pill);
  background-color: var(--color-white);
  color: var(--color-text);
  font-size: var(--font-size-md);
  line-height: 1.4;
}

.chip > i {
  font-size: 0.85em;
}

.chip--on {
  border-color: var(--color-brand-green);
  background-color: var(--color-brand-tint);
  color: var(--color-brand-green-dark);
  font-weight: var(--font-weight-semibold);
}

.chip--off {
  background-color: transparent;
  color: var(--color-text-muted);
}
/* ==========================================================================
   Waiver Components
   Shared styles for waiver functionality across modules:
   - Custom Registration
   - Event Registration
   - Waiver Agreements
   ========================================================================== */

/* Checkbox Input Styling
   Visual feedback for waiver checkbox state
   ========================================================================== */

.checkbox-input {
  display: flex;
  flex-direction: row;
  margin-top: 10px;
  padding: 10px;
  align-items: center;
}

.checkbox-input > label {
  margin: 0;
}

/* Checkbox State Classes
   ========================================================================== */

.unchecked {
  background-color: var(--color-danger-bg);
  border: 2px solid var(--color-danger);
}

.checked {
  background-color: var(--color-success-bg);
  border: 2px solid var(--color-success);
}

/* Waiver Embedded (Inline scroll container — non-overlay, non-modal)
   Used by Custom Registration and Event Registration waiver steps.
   The waiver inset is viewport-anchored: bounded height + own scroll,
   so the surrounding page (header, nav) stays put. The
   .agreement-button-container sticks to the bottom of this scroll context.
   ========================================================================== */

.waiver-embedded {
  max-height: calc(100vh - 200px);
  overflow-y: auto;
  background: var(--color-white);
  border-radius: var(--radius-md);
  padding: 30px 0 0;
}

/* Waiver Modal (Bounded card with backdrop — dismissible)
   Used by Update Personal Information's adult waiver re-sign flow.
   Everything inside .waiver-modal-body scrolls together (no fixed footer).
   ========================================================================== */

.waiver-modal-overlay {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  /* Explicit dimensions in case an ancestor's containing block defeats
     the inset: 0 / top/right/bottom/left approach. */
  width: 100vw;
  height: 100vh;
  background: rgba(0, 0, 0, 0.55);
  display: flex;
  justify-content: center;
  align-items: center;
  z-index: 2000;
  padding: var(--space-5);
  box-sizing: border-box;
}

.waiver-modal {
  background: var(--color-white);
  border-radius: var(--radius-lg);
  width: 100%;
  max-width: 960px;
  max-height: 90vh;
  /* Fallback centering — works even if the flex parent's centering is
     defeated by an ancestor's containing-block (transformed/filtered
     parent in the HubSpot CMS wrapper). */
  margin: 0 auto;
  display: flex;
  flex-direction: column;
  box-shadow: 0 10px 40px rgba(0, 0, 0, 0.25);
  /* Clip children to the rounded modal shape so the sticky footer
     doesn't bleed past the bottom-corner radius. */
  overflow: hidden;
}

.waiver-modal-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: var(--space-4) var(--space-6);
  border-bottom: 1px solid var(--color-border);
  flex-shrink: 0;
}

.waiver-modal-header h3 {
  margin: 0;
  font-size: var(--font-size-lg);
}

.waiver-modal-close {
  font-size: 28px;
  line-height: 1;
  color: var(--color-text);
  padding: var(--space-1) var(--space-3);
}

.waiver-modal-close:hover {
  color: var(--color-black);
}

.waiver-modal-body {
  overflow-y: auto;
  flex: 1;
  padding: var(--space-6);
}

/* Inside the modal, .agreement-button-container is a sibling of
   .waiver-modal-body (not inside it). The modal's flex column places it
   at the bottom of the modal naturally; override the global sticky/fixed
   positioning so it sits inline at the modal's bottom edge. */
.waiver-modal > .agreement-button-container {
  position: static;
  z-index: auto;
  box-shadow: none;
  flex-shrink: 0;
}

/* When the acc_waiver / ast_waiver macro is rendered inside the modal body,
   adjust the macro's internal layout for the narrower modal container. */
.waiver-modal-body .waiver-module-inside {
  width: 100%;
  padding: 0;
}

.waiver-modal-body .header-content {
  text-align: center;
  width: 100%;
  margin: 0 0 var(--space-4) 0;
}

.waiver-modal-body .header-content img {
  margin-bottom: 8px;
}

@media (max-width: 768px) {
  .waiver-modal-overlay {
    padding: 0;
  }
  .waiver-modal {
    max-height: 100vh;
    /* Dynamic viewport height — accounts for iOS Safari URL bar
       shrink/grow so the modal doesn't overflow below the visible area.
       Older browsers ignore this line and fall back to vh above. */
    max-height: 100dvh;
    border-radius: 0;
  }
}

.waiver-embedded .header-content {
  text-align: center;
  width: 90%;
  margin: 0 auto;
  max-width: 1200px;
}

.waiver-parent {
  overflow-y: hidden;
}

/* Waiver Module Blocks
   ========================================================================== */

.waiver-module-block {
  padding: 10px;
  background: var(--color-bg-page);
  border-radius: var(--radius-pill);
  margin-bottom: 50px;
}

.waiver-embedded .waiver-module-block {
  margin-bottom: 80px;
}

.waiver-module-inside {
  max-width: 1200px;
  width: 95%;
  margin: 0 auto;
  padding: 0 25px;
}

.waiver-module-agreement > div {
  text-align: center;
}

/* Waiver Version Label
   ========================================================================== */

.waiver-version {
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
  margin: var(--space-1) 0 var(--space-2);
}

/* Waiver Checkbox Counter
   Live progress indicator for checkbox completion
   ========================================================================== */

.waiver-checkbox-counter {
  font-size: var(--font-size-md);
  font-weight: var(--font-weight-semibold);
  color: var(--color-danger-text);
  margin: 0 0 5px;
}

.waiver-checkbox-counter.all-checked {
  color: var(--color-success);
}

/* Waiver Header Styling
   ========================================================================== */

.waiver-header {
  background-color: #ffff00;
  border: 2px solid var(--color-danger);
  text-align: center;
}

.waiver-subheader {
  background-color: #ffff00;
  border: 2px solid var(--color-danger);
  text-align: left;
  padding: 15px;
}

.waiver-bold-text {
  font-weight: var(--font-weight-bold);
}

.waiver-header-block {
  background-color: #ffff00;
  border: 3px solid var(--color-danger);
  display: flex;
  flex-direction: row;
}

/* Waiver Block Layout
   ========================================================================== */

.waiver-block {
  display: flex;
  flex-direction: row;
}

.small-sub-block {
  width: 10%;
  min-width: 40px;
  padding-left: 5px;
}

.large-sub-block {
  width: 90%;
}

/* Agreement Button Container
   Sticks to the bottom of the scrolling parent (the waiver container in
   full-screen flows, or the modal body in the UPI modal). The header and
   waiver body scroll above; this footer stays visible.
   ========================================================================== */

.agreement-button-container {
  padding: var(--space-5);
  display: flex;
  flex-direction: column;
  justify-content: center;
  position: sticky;
  align-items: center;
  bottom: 0;
  background: var(--color-white);
  border-top: 1px solid var(--color-border);
  z-index: 10;
}

/* Signature Section
   ========================================================================== */

.signature-section {
  padding: var(--space-5);
  background: var(--color-bg-page);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  width: 100%;
  max-width: 800px;
  box-sizing: border-box;
}

.name-input-container {
  display: flex;
  align-items: center;
  gap: var(--space-5);
  max-width: 600px;
  margin: 0 auto;
  position: relative;
}

.name-input-container label {
  flex-shrink: 0;
  font-weight: var(--font-weight-semibold);
  color: var(--color-text);
  margin-bottom: 0;
}

.waiver-name-input {
  flex: 1;
}

.name-validation-message {
  position: absolute;
  top: calc(100% + 5px);
  left: 0;
  right: 0;
  margin-top: 8px;
  padding: var(--space-2) var(--space-3);
  background: var(--color-warning-bg);
  border: 1px solid var(--color-warning);
  border-radius: var(--radius-sm);
  color: var(--color-warning-text);
  font-size: var(--font-size-md);
}

.validation-warning {
  display: block;
  text-align: center;
}

.button-wrapper {
  text-align: center;
  margin-top: 20px;
}

/* Waiver submit sits at the end of its row, like the primary action on every
   other step of the registration flow (this container is a flex column, so
   align-self is the horizontal one). */
.agreement-button-container > button {
  align-self: flex-end;
}

/* Waiver Mobile Styles
   ========================================================================== */

@media (max-width: 600px) {
  .waiver-module-inside {
    width: 100%;
    padding: 0 5px;
  }

  .waiver-module-block {
    padding: 5px;
  }

  .header-content {
    width: 100%;
  }

  .name-input-container {
    flex-direction: column;
    align-items: stretch;
    gap: 10px;
  }

  .name-input-container label {
    margin-bottom: 8px;
  }

  /* Stacked, `flex: 1` would size the field's height from a zero basis. */
  .waiver-name-input {
    flex: none;
    width: 100%;
  }
}

@media (max-width: 480px) {
  .agreement-button-container {
    padding: 15px;
  }
}

/* Contact Info Display
   Two-column label + value layout for waiver contact details. The grid lives
   on the outer .contact_info_display so all rows share the same label-column
   width (max-content takes the widest label); `display: contents` on the
   per-row wrapper lets the labels and values participate directly in the
   parent grid.
   ========================================================================== */

.contact_info_display {
  display: grid;
  grid-template-columns: max-content 1fr;
  column-gap: var(--space-3);
  row-gap: var(--space-1);
  align-items: baseline;
}

.contact_info_display .field-group-2 {
  display: contents;
}

.contact_info_display .field-group-2 label {
  padding-top: 0;
}

.contact_info_display .field-group-2 > div {
  width: auto;
}

@media (max-width: 480px) {
  .contact_info_display {
    grid-template-columns: 1fr;
  }
}
/* ==========================================================================
   Custom Form Components
   Styles for custom login, password reset, and booking forms
   ========================================================================== */

/* Booking Module Form
   Form layout for event booking modules
   ========================================================================== */

.booking-module-form-inside fieldset .input {
  margin: 0 !important;
}

.booking-module-form-inside fieldset.form-columns-3 > div {
  width: calc(33.33% - 13.33px) !important;
}

.booking-module-form-inside fieldset.form-columns-2 > div {
  width: calc(50% - 10px) !important;
}

.booking-module-form-inside fieldset.form-columns-1 > div {
  width: 100% !important;
}

.booking-module-form-inside fieldset {
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
  gap: var(--space-5);
}

/* Field groups (Custom Registration, Update Personal Information)
   Two or three fields side by side, one per row on a phone. Each form keeps
   its own gap.
   ========================================================================== */

.field-group-2,
.field-group-3 {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  align-content: flex-start;
  align-items: flex-start;
  gap: 15px;
}

.field-group-2 > div {
  width: calc(50% - 15px);
}

.field-group-3 > div {
  width: calc(33.33% - 15px);
}

@media only screen and (max-width: 800px) {
  .field-group-2 > div,
  .field-group-3 > div {
    width: 100%;
  }
}

/* Login Widget Remember Me Checkbox
   ========================================================================== */

input#hs-login-widget-remember {
  display: inline-block;
  vertical-align: middle;
}

label[for='hs-login-widget-remember'] {
  display: inline-block;
  vertical-align: middle;
  line-height: 20px;
  margin: 0;
}

#hs_login_reset {
  display: none;
}

/* Password Reset Form
   ========================================================================== */

.custom-password-reset-form-container {
  width: 100%;
  max-width: 400px;
}

.custom-password-reset-form-container-parent {
  display: flex;
  justify-content: center;
  align-items: center;
}

.password-reset-form .hs-form-field {
  padding-bottom: 30px;
  margin-bottom: 0;
  background-color: transparent !important;
}

.password-reset-form .hs-button {
  margin-top: 0 !important;
  width: 100%;
}

.password-reset-form .actions {
  background-color: transparent;
}

.password-reset-form .form-input-validation-message {
  background-color: transparent !important;
  margin-bottom: 0 !important;
  padding-bottom: 16px;
}

.password-reset-form label {
  margin-bottom: 0 !important;
}

/* Login Form
   ========================================================================== */

.custom-login-form-container {
  width: 100%;
  max-width: 450px;
}

.custom-login-form-container-parent {
  display: flex;
  justify-content: center;
  align-items: center;
}

.custom-login-form .hs-form-field {
  padding-bottom: 30px;
  margin-bottom: 0;
  background-color: transparent !important;
}

.custom-login-form .hs-button {
  margin-top: 0;
  width: 100%;
}

.custom-login-form .actions {
  background-color: transparent;
}

/* Login Form - Login Button Spacing
   ========================================================================== */

.custom-login-form > .hs-membership-loader .actions {
  margin-bottom: 20px;
}

#hs-membership-form {
  padding: 0 0 var(--space-5) 0;
  margin-bottom: 0;
}

/* Passwordless Login Form
   Card wrapper, checkbox, and button overrides for the passwordless section
   ========================================================================== */

#hs-membership-passwordless-auth-form {
  padding: var(--space-5) 0 0 0;
  margin-top: 0;
}

#hs-membership-passwordless-auth-form .hs-form-field {
  background-color: transparent;
  padding-bottom: 15px;
}

#hs-membership-passwordless-auth-form .actions {
  background-color: transparent;
}

/* The secondary look (D4: white, navy outline). The ID and !important beat
   the primary `form .hs-button` alias this HubSpot button also carries. */
#hs-membership-passwordless-auth-form #hs-passwordless-submit {
  background-color: var(--color-white) !important;
  border: 1px solid var(--color-navy) !important;
  color: var(--color-navy) !important;
}
#hs-membership-passwordless-auth-form
  #hs-passwordless-submit:is(:hover, :focus) {
  background-color: var(--color-bg-subtle) !important;
}

/* Passwordless Consent Checkbox
   ========================================================================== */

input#hs-passwordless-auth-explicit-consent {
  display: inline-block;
  min-width: 20px;
  vertical-align: middle;
}

label#hs-passwordless-auth-checkbox-consent {
  display: inline;
  vertical-align: middle;
  line-height: 20px;
  margin: 0;
}

/* Login Card
   Outer card wrapping Google sign-in, divider, and login forms
   ========================================================================== */

.login-card {
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  padding: 25px;
  margin-bottom: 15px;
  background-color: var(--color-white);
}

/* Login Divider
   "Or sign in with email" separator between social login and form
   ========================================================================== */

.login-divider {
  display: flex;
  align-items: center;
  margin: var(--space-5) 0;
  color: var(--color-placeholder);
  font-size: var(--font-size-sm);
}

.login-divider::before,
.login-divider::after {
  content: '';
  flex: 1;
  border-bottom: 1px solid var(--color-border);
}

.login-divider span {
  padding: 0 var(--space-3);
}

/* Login Bottom Links
   Forgot password link below the form
   ========================================================================== */

.login-bottom-links {
  padding-top: 10px;
}

.login-bottom-links p {
  margin: 0;
  font-size: var(--font-size-md);
}

/* Login Help Section
   "Can't log in?" troubleshooting section
   ========================================================================== */

.login-help-section {
  margin-top: 20px;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  padding: 25px;
  background-color: var(--color-white);
}

.login-help-header {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  margin-bottom: 15px;
  font-weight: var(--font-weight-semibold);
  font-size: var(--font-size-md);
  color: var(--color-text);
}

.login-help-header i {
  color: var(--color-brand-green);
  font-size: var(--font-size-md);
  background: var(--color-success-bg);
  width: 28px;
  height: 28px;
  border-radius: var(--radius-circle);
  display: inline-flex;
  align-items: center;
  justify-content: center;
}

.login-help-row {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 10px 0;
  border-bottom: 1px solid var(--color-bg-muted);
  font-size: var(--font-size-md);
}

.login-help-row:last-child {
  border-bottom: none;
}

.login-help-row span {
  color: var(--color-text-secondary);
}

.login-help-row a {
  white-space: nowrap;
  margin-left: 12px;
}

/* Login Footer Link
   "Not a member yet? Join the ACC" link
   ========================================================================== */

.login-footer-link {
  text-align: center;
  margin-top: 25px;
}

.login-footer-link p {
  margin: 0;
  font-size: var(--font-size-md);
  color: var(--color-placeholder);
}

.login-footer-link a {
  color: var(--color-brand-green);
  text-decoration: underline;
}

.login-footer-link a:hover {
  color: var(--color-brand-green);
  text-decoration: underline;
}

/* Custom Login Page Layout
   Split-screen login page with background image
   ========================================================================== */

section.custom-login-page {
  position: relative;
  flex-grow: 1;
}

.custom-login-page-container {
  max-width: 50%;
  padding: var(--space-10);
  z-index: 9;
  position: relative;
  min-height: 825px;
  box-sizing: border-box;
}

section.custom-login-page:before {
  content: '';
  position: absolute;
  top: 0;
  right: 0;
  width: 50%;
  height: 100%;
  background-image: url('https://48952529.fs1.hubspotusercontent-na1.net/hubfs/48952529/Image%20Assets/018A6243-Edit.png');
  background-size: cover;
  background-position: center;
}

.custom-login-page-container button {
  background: var(--color-white) !important;
  border: 3px solid var(--color-brand-green) !important;
  color: var(--color-black) !important;
}

.custom-login-page-container .form-oauth {
  padding-top: 10px !important;
  padding-bottom: 0 !important;
}

.login-card .g_id_signin {
  padding-top: 10px;
}

/* Form Container
   ========================================================================== */

.form-container {
  padding: 5px;
}

/* Mobile Responsive Forms
   ========================================================================== */

@media only screen and (max-width: 1000px) {
  .custom-login-page-container {
    max-width: 100%;
    width: 100%;
    padding: var(--space-5);
    min-height: auto;
  }

  section.custom-login-page:before {
    display: none;
  }

  .login-help-row {
    flex-direction: column;
    align-items: flex-start;
    gap: var(--space-1);
  }

  .login-help-row a {
    margin-left: 0;
  }
}

/* ACC-1770 — the phone field (phone_field macro): the country-code picker and
   the number box side by side, the box taking the rest of the row. Closed,
   the picker is a button showing only its code, drawn like a select and sized
   for the longest code, "+998". Open, a search box sits over the country
   list, which reuses the address suggestions' look (below). */
.acc-phone {
  position: relative;
  display: flex;
  gap: var(--space-2);
}

.acc-phone-dial-box {
  flex: 0 0 auto;
}

/* The field look comes from the shared field rule (elements/_forms.css);
   this adds the select's chevron. */
.acc-phone-dial-code {
  display: flex;
  align-items: center;
  width: calc(4ch + 58px);
  padding-right: 44px;
  background-image: var(--icon-select-chevron);
  background-position: right 14px center;
  background-repeat: no-repeat;
  background-size: 16px;
  white-space: nowrap;
  text-align: left;
  cursor: pointer;
}

/* Open, it keeps the focus look while focus is in the search box. Its
   focus, invalid and disabled looks are the shared field's
   (elements/_forms.css). */
.acc-phone-dial-code[aria-expanded='true'] {
  border-color: var(--color-brand-green);
  box-shadow: var(--shadow-focus);
}

.acc-phone .acc-phone-number {
  flex: 1 1 0;
  min-width: 0;
}

/* On a phone the row can be as short as 224px (sign-up at 360px wide). The
   button and the box give up some padding there, so a ten-digit number still
   shows whole beside the longest code. */
@media only screen and (max-width: 480px) {
  .acc-phone-dial-code {
    width: calc(4ch + 38px);
    padding-left: var(--space-2);
    padding-right: 30px;
    background-position: right var(--space-2) center;
  }

  .acc-phone .acc-phone-number {
    padding: 0 var(--space-3);
  }
}

/* The list opens under the field, from its left edge: wider than the button,
   never wider than the field, so it stays on a phone's screen. */
.acc-address-suggest.acc-phone-dial-pop {
  right: auto;
  width: min(100%, 320px);
}

/* The search box and its magnifier are the address search's
   (.acc-address-combo, below), on a strip above the list. */
.acc-phone-dial-search {
  margin: var(--space-2);
}

/* Positioned, so an option's offset is measured from the list that scrolls;
   a line divides it from the search box. */
.acc-phone-dial-pop ul {
  position: relative;
  border-top: 1px solid var(--color-border);
}

.acc-phone-dial-pop li {
  flex-wrap: nowrap;
  justify-content: space-between;
}

.acc-phone-dial-pop li.is-current .acc-phone-dial-name {
  font-weight: var(--font-weight-semibold);
}

.acc-address-suggest li.acc-phone-dial-sep {
  height: 1px;
  margin: var(--space-1) 0;
  padding: 0;
  background: var(--color-border);
}

.acc-address-suggest li.acc-phone-dial-empty {
  color: var(--color-text-secondary);
}

/* ACC-1770 — the date-of-birth field (date-field.js): a box to type
   YYYY-MM-DD in, with a calendar button inside its right edge. The button
   opens a popover: Cally's day grid, and over it our year and month grids. */
.acc-date {
  position: relative;
}

.acc-date > input {
  padding-right: 52px;
}

.acc-date-btn {
  position: absolute;
  top: 4px;
  right: 4px;
  color: var(--color-brand-green);
}

.acc-date-btn svg {
  width: 20px;
  height: 20px;
}

/* Cally didn't load: the date is typed. */
.acc-no-calendar .acc-date-btn {
  display: none;
}

/* The scroll margin is a little air under it when date-field.js scrolls it
   into view. */
.acc-date-pop {
  position: absolute;
  top: calc(100% + var(--space-1));
  right: 0;
  z-index: var(--z-dropdown);
  scroll-margin-bottom: var(--space-3);
  padding: var(--space-3);
  background: var(--color-white);
  border: 1px solid var(--color-border-input);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-md);
}

/* Cally is styled through its parts; these two are its own colour hooks. */
.acc-date-pop calendar-date,
.acc-date-pop calendar-month {
  --color-accent: var(--color-brand-green);
  --color-text-on-accent: var(--color-white);
}

.acc-date-pop calendar-date {
  font-family: inherit;
  color: var(--color-text);
}

.acc-date-pop calendar-date::part(header) {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-1);
  margin-bottom: var(--space-2);
}

/* The square icon buttons: the field's own, Cally's previous / next month,
   and the grids' earlier / later. */
.acc-date-btn,
.acc-cal-nav,
.acc-date-pop calendar-date::part(button) {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  border: 0;
  border-radius: var(--radius-md);
  background: transparent;
  cursor: pointer;
}

.acc-cal-nav,
.acc-date-pop calendar-date::part(button) {
  color: var(--color-navy);
}

/* The title ("March 1985") opens the year grid, then the month grid. */
.acc-cal-title {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  height: 36px;
  padding: 0 var(--space-3);
  border-radius: var(--radius-md);
  color: var(--color-navy);
  font-size: var(--font-size-base);
  font-weight: var(--font-weight-semibold);
}

.acc-cal-title svg {
  width: 14px;
  height: 14px;
}

.acc-date-btn:hover,
.acc-date-btn[aria-expanded='true'],
.acc-cal-nav:hover,
.acc-cal-title:hover,
.acc-cal-title[aria-expanded='true'],
.acc-cal-jump-grid button:hover,
.acc-date-pop calendar-date::part(button):hover {
  background: var(--color-brand-tint);
}

/* What can't be chosen: a future year or month, the end of the range. */
.acc-cal-nav:disabled,
.acc-cal-jump-grid button:disabled,
.acc-date-pop calendar-date::part(disabled) {
  background: none;
  opacity: 0.35;
  cursor: default;
}

.acc-cal-title:disabled {
  background: none;
  cursor: default;
}

/* The month's name is in the title button; keep Cally's for screen readers. */
.acc-date-pop calendar-month::part(heading) {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}

.acc-date-pop calendar-month::part(th) {
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-semibold);
  color: var(--color-text-secondary);
}

.acc-date-pop calendar-month::part(button) {
  border-radius: var(--radius-md);
  cursor: pointer;
}

.acc-date-pop calendar-month::part(today),
.acc-cal-jump-grid button.is-now {
  box-shadow: inset 0 0 0 1px var(--color-brand-green);
}

.acc-date-pop calendar-month::part(selected) {
  font-weight: var(--font-weight-semibold);
}

/* Cally fills the day in keyboard focus exactly like the chosen day. Told
   apart: focus is a tint with a ring, the chosen day stays filled. */
.acc-date-pop calendar-month::part(day):focus-visible {
  background: var(--color-brand-tint);
  color: var(--color-text);
  outline: 2px solid var(--color-brand-green);
  outline-offset: -2px;
}

.acc-date-pop calendar-month::part(selected):focus-visible {
  background: var(--color-brand-green);
  color: var(--color-white);
  outline-color: var(--color-white);
  outline-offset: -4px;
}

.acc-cal-jump {
  position: absolute;
  inset: var(--space-3);
  display: flex;
  flex-direction: column;
  background: var(--color-white);
}

.acc-cal-jump[hidden] {
  display: none;
}

.acc-cal-jump-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: var(--space-2);
}

.acc-cal-jump-grid {
  flex: 1;
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  grid-auto-rows: minmax(36px, 1fr);
  gap: var(--space-1);
}

.acc-cal-jump-grid button {
  border-radius: var(--radius-md);
  color: var(--color-text);
  font-size: var(--font-size-md);
}

.acc-cal-jump-grid button[aria-pressed='true'] {
  background: var(--color-brand-green);
  color: var(--color-white);
  font-weight: var(--font-weight-semibold);
}

/* ACC-1770 — address suggestions under line 1 (address_search macro,
   ACC_Address): the input stays the form's own; the list floats under it. */
.acc-address-combo {
  position: relative;
}

/* The magnifying glass inside line 1, while suggestions are live (the
   combobox role goes when they fall back to a plain field). */
.acc-address-combo-icon {
  position: absolute;
  left: var(--space-3);
  top: 50%;
  width: 1rem;
  height: 1rem;
  transform: translateY(-50%);
  color: var(--color-text-secondary);
  pointer-events: none;
}

.acc-address-combo > input[role='combobox'] {
  padding-left: calc(var(--space-3) + 1rem + var(--space-2));
}

.acc-address-suggest {
  position: absolute;
  top: 100%;
  left: 0;
  right: 0;
  z-index: var(--z-dropdown);
  margin-top: var(--space-1);
  background: var(--color-white);
  border: 1px solid var(--color-border-input);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-md);
  overflow: hidden;
}

.acc-address-suggest ul {
  list-style: none;
  margin: 0;
  padding: var(--space-1) 0;
  max-height: 18rem;
  overflow-y: auto;
}

.acc-address-suggest li {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  column-gap: var(--space-2);
  padding: var(--space-2) var(--space-3);
}

/* Only a choice reacts: the phone picker's list also has a dividing line and
   a "no match" row. */
.acc-address-suggest li[role='option'] {
  cursor: pointer;
}

.acc-address-suggest li[role='option']:hover,
.acc-address-suggest li[aria-selected='true'] {
  background: var(--color-brand-tint);
}

.acc-address-suggest-rest {
  color: var(--color-text-secondary);
  font-size: var(--font-size-sm);
}

/* Google's terms: "Google Maps" under its suggestions, in its own font, size
   and colour, never translated. */
.acc-address-suggest .acc-address-credit {
  margin: 0;
  padding: var(--space-1) var(--space-3) var(--space-2);
  text-align: right;
  font-family: Roboto, sans-serif;
  font-size: var(--font-size-xs);
  color: var(--color-google-attribution);
}
/* ==========================================================================
   Parent-Info Gate
   Shared styling for the under-age parent-info form rendered inside the
   waiver flow in Custom Registration, Waiver Agreements, and Update Personal
   Information. Centralized here because the same component renders in three
   places — keeps the visual treatment consistent and avoids per-module CSS
   drift.
   ========================================================================== */

.parent-info-card {
  max-width: 560px;
  margin: 0 auto;
  padding: var(--space-8);
  background: var(--color-bg-muted);
  border-radius: var(--radius-xl);
  box-sizing: border-box;
}

/* ACC logo at the top of the card — matches the .header-content treatment
   used by acc_waiver() and minor_waiver(), so the parent-info gate (which
   replaces those macros inside the same modal) shares a first impression. */
.parent-info-logo {
  display: block;
  margin: 0 auto var(--space-5);
  width: 150px;
  height: auto;
}

/* Inside the waiver modal the card sits in an already-padded white panel,
   so the grey box-in-box reads as too much chrome. Strip the chrome and
   keep just the centered width — the modal itself is the card. */
.waiver-modal-body .parent-info-card {
  padding: 0;
  background: transparent;
  border-radius: 0;
}

/* Pending-state cards stay chromeless everywhere — they're status messages
   rather than forms, and the icon + centered text already read as a card. */
.parent-info-card.parent-info-pending {
  padding: var(--space-2) 0 var(--space-1);
  background: transparent;
  border-radius: 0;
}

.parent-info-heading {
  margin: 0 0 var(--space-3) 0;
  font-size: var(--font-size-xl);
  font-weight: var(--font-weight-bold);
  color: var(--color-navy);
  text-align: center;
}

.parent-info-subtext {
  margin: 0 0 var(--space-6) 0;
  font-size: var(--font-size-md);
  line-height: 1.5;
  color: var(--color-text-body);
}

/* Field rows — stack label above input, consistent spacing top to bottom.
   The label and field take the shared form look (elements/_forms.css),
   inside a <form> or not. */
.parent-info-field {
  margin-bottom: 16px;
}

/* Submit button sits inside .button-wrapper (existing waiver-modal footer
   convention); no override needed — inherits .clickable-button styles from
   src/css/elements/_buttons.css. */

/* Pending state: centered "Waiting on parent signature" status. Subtext
   also centers here (overrides the default left-aligned subtext) so the
   status reads as a balanced message rather than a form prompt. Card chrome
   is stripped in the .parent-info-card.parent-info-pending rule above. */
.parent-info-pending .parent-info-subtext {
  text-align: center;
}

/* Inline variant (UPI's right-column Waiver section): left-aligned to match
   the surrounding Status/Signed/Expires labels, with a clock icon next to
   the heading. The modal pending state stays centered. */
.parent-info-pending--inline .parent-info-heading,
.parent-info-pending--inline .parent-info-subtext {
  text-align: left;
}

.parent-info-pending--inline .parent-info-heading i {
  margin-right: 6px;
  color: var(--color-brand-green);
}

/* Center the resend button in the centered (modal) pending state so it lines up
   under the heading/subtext. The inline variant (UPI) stays left-aligned, so its
   button is left untouched. */
.parent-info-pending:not(.parent-info-pending--inline) .accept-button {
  display: block;
  width: fit-content;
  margin-left: auto;
  margin-right: auto;
}

/* Mobile. The card's 32px padding on top of the host page's own side padding
   leaves a cramped column on a small phone — measured 216px of usable width at
   a 320px viewport on the Gazette confirmation page. Reduce to 20px at the
   theme's dominant breakpoint (768px, 15 uses).

   Deliberately a BARE .parent-info-card selector (0,1,0). A media query adds no
   specificity, so the two existing context overrides — .waiver-modal-body
   .parent-info-card and .parent-info-card.parent-info-pending, both 0,2,0 —
   keep winning. The waiver-modal and pending states are therefore untouched by
   this rule; only full-chrome cards change.

   That covers every full-chrome render site, all of which gain: the Gazette
   confirmation page, the minor-waiver signing page, the hut-booking removal
   page, and the parent gate in Event Registration, Waiver Agreements, Custom
   Registration and Update Personal Information. Verified none of those modules
   carries its own .parent-info-* rule inside a media query, so there is nothing
   to double-reduce against. Padding only — no flow, width or position change,
   so it cannot reorder or reflow any of them. */
@media (max-width: 768px) {
  .parent-info-card {
    padding: var(--space-5);
  }
}
/*
 * Step progress — the shared step indicator for multi-step flows (D17,
 * docs/style-audit.md). The step panels at the end are toggled by
 * ACC_STEP_MACHINE.
 */

.step-progress {
  display: flex;
  margin: var(--space-5) 0;
  /* For the modules that mark it up as an <ol>. */
  padding: 0;
  list-style: none;
}

.step-progress .progress-step {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-2);
  position: relative;
  flex: 1;
  /* Steps must stay equal: each line is placed from its own step's width, and
     a long label would otherwise widen its step. */
  min-width: 0;
}

/* The line from the previous circle to this one, for every step that has a
   visible step before it. It stops 2px short of each 28px circle. */
.step-progress .progress-step:not(.skipped) ~ .progress-step::before {
  content: '';
  position: absolute;
  top: 13px;
  left: calc(-50% + 16px);
  right: calc(50% + 16px);
  height: 2px;
  background: var(--step-line, var(--color-border-strong));
}

/* The line leading into the current step, and into each finished one. */
.step-progress .progress-step.active,
.step-progress .progress-step.completed {
  --step-line: var(--color-brand-green);
}

.step-progress .step-number {
  width: 28px;
  height: 28px;
  border: 2px solid var(--color-border-strong);
  border-radius: var(--radius-circle);
  background: var(--color-white);
  color: var(--color-text-secondary);
  display: flex;
  align-items: center;
  justify-content: center;
  font-weight: var(--font-weight-semibold);
  font-size: var(--font-size-sm);
  transition: background-color 0.2s ease, border-color 0.2s ease,
    box-shadow 0.2s ease;
}

.step-progress .step-label {
  max-width: 100%;
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
  text-align: center;
  /* A long word breaks inside its step. */
  overflow-wrap: anywhere;
  hyphens: auto;
}

/* Current step */
.step-progress .progress-step.active .step-number {
  border-color: var(--color-brand-green);
  color: var(--color-brand-green);
  box-shadow: 0 0 0 4px rgba(47, 119, 81, 0.2);
}

.step-progress .progress-step.active .step-label {
  color: var(--color-navy);
  font-weight: var(--font-weight-semibold);
}

/* Completed step */
.step-progress .progress-step.completed .step-number {
  position: relative;
  border-color: var(--color-brand-green);
  background: var(--color-brand-green);
  /* The tick is drawn over the number, which stays in the markup: the step
     machine rewrites it, and the style guardrail bars `font-size: 0`. */
  color: transparent;
}

.step-progress .progress-step.completed .step-number::after {
  content: '✓';
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--color-white);
}

.step-progress .progress-step.skipped {
  display: none;
}

/* Step panels — toggled by ACC_STEP_MACHINE via [hidden] + .active-step */
.reg-step[hidden] {
  display: none;
}

/* Step + notice headings are programmatic focus targets for the machine's
   a11y announcements (tabindex="-1", never tab-reachable) — no focus ring. */
[data-step-heading] {
  outline: none;
}

@media only screen and (max-width: 700px) {
  .step-progress .step-label {
    font-size: var(--font-size-xs);
  }
}
/* ==========================================================================
   System Pages
   Styles for HubSpot system pages (error pages, search results, etc.)
   ========================================================================== */

/* System Page Content
   Main content area for system pages
   ========================================================================== */

.system-page-content {
  text-align: center;
  padding: 15px 0;
  margin: 0;
}

/* System Page Branding
   Logo/branding area for system pages
   ========================================================================== */

.system-page-branding img {
  width: 200px;
  display: block;
  margin: 0 auto;
}

/* System Page Details
   Call-to-action section on system pages
   ========================================================================== */

.system-page-details {
  text-align: center;
  padding: 50px 15px;
  background: var(--color-bg-page);
  border-radius: var(--radius-pill);
  margin-top: 50px;
}

.system-page-details h4 {
  margin-top: 0;
  color: var(--color-navy);
}

.system-page-details a {
  display: inline-block;
  padding: 15px var(--space-10);
  background: var(--color-navy);
  text-decoration: none;
  text-transform: uppercase;
  font-size: var(--font-size-base);
  color: var(--color-white);
  font-weight: var(--font-weight-bold);
  border-radius: var(--radius-button);
  min-width: 200px;
  text-align: center;
  margin: 0 5px;
}

/* System Page Details Container
   Wrapper for system page details
   ========================================================================== */

.system-page-details-container {
  padding-top: 25px;
}

.system-page-details-container h4 {
  margin: 0;
  padding-bottom: 10px;
}

.system-page-details-container a {
  display: block;
  color: var(--color-black);
}

/* Search Results
   HubSpot search results page styling
   ========================================================================== */

.hs-search-field__form {
  background-color: rgba(248, 248, 248, 1);
}

/* HubSpot's search button takes the primary look (elements/_buttons.css). */

/* Card the whole search-results module (title + listing) on a white card, matching the
   portal modules. The title and the listing are the module wrapper's only two children,
   so carding the wrapper keeps them together in one card. */
.hs_cos_wrapper:has(> .hs-search-results) {
  background: var(--color-white);
  border-radius: var(--radius-button);
  padding: 25px;
  margin-top: var(--space-5);
}

/* Results title acts as the card heading (green, with a divider), like .module-header. */
.hs-search-results-title {
  margin: 0 0 15px;
  padding-bottom: 15px;
  border-bottom: 1px solid var(--color-bg-muted);
  color: var(--color-brand-green);
  font-size: var(--module-heading-size, var(--font-size-2xl));
}

/* Before a search runs the listing has no result elements (just whitespace). Show a
   centred prompt with a search icon instead of a blank card. Uses :not(:has(*)) rather
   than :empty because the container isn't truly empty.
   The module renders results client-side, so the container is also briefly empty on
   every page load (fresh search, pagination); the animation holds the prompt back so
   it doesn't flash before results paint. (The module's JS exposes no loading-state
   class to key off instead — it only ever injects the finished listing.) */
.hs-search-results:not(:has(*)) {
  text-align: center;
  padding: 70px 15px 25px;
  background-repeat: no-repeat;
  background-position: center 18px;
  background-image: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' width='44' height='44' viewBox='0 0 24 24' fill='none' stroke='%232f7751' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><circle cx='11' cy='11' r='7'/><line x1='21' y1='21' x2='16.65' y2='16.65'/></svg>");
  animation: search-empty-prompt 0.15s ease 0.4s backwards;
}

@keyframes search-empty-prompt {
  from {
    opacity: 0;
  }
}

.hs-search-results:not(:has(*))::before {
  content: 'Enter a search term above to find huts, events, membership info, and more.';
  display: block;
  color: var(--color-placeholder);
}

html[lang^='fr'] .hs-search-results:not(:has(*))::before {
  content: "Entrez un terme de recherche ci-dessus pour trouver refuges, événements, renseignements sur l'adhésion et plus encore.";
}
/* ===========================================
   Shared Modal Styles
   Reusable overlay + card + button pattern.
   Add the .confirm-modal class to the overlay div,
   toggle .active to show/hide.
   =========================================== */

/* Overlay */
.confirm-modal {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background-color: rgba(0, 0, 0, 0.5);
  display: flex;
  justify-content: center;
  align-items: center;
  /* Above a record sheet: the address check opens over the profile form's
     sheet, and on a z-index tie the later element in <body> wins. */
  z-index: var(--z-dialog);
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.3s ease, visibility 0.3s ease;
}

.confirm-modal.active {
  opacity: 1;
  visibility: visible;
  /* Repeated from the base rule on purpose: a module stylesheet carrying its
     own bare `.active { display: block }` has the same specificity as
     `.confirm-modal` but loads later, which silently turned the overlay into
     a block and pinned the card to the top-left corner. Qualifying with both
     classes wins regardless of load order. */
  display: flex;
}

/* Bare close control for a modal header (×): new modals and the Staffed Trips
   report modal use this. The waiver modal and the record sheet keep their own
   (different containers). */
.confirm-modal .modal-close {
  flex-shrink: 0;
  font-size: var(--font-size-2xl);
  line-height: 1;
  color: var(--color-text-secondary);
  padding: var(--space-1);
}
.confirm-modal .modal-close:hover,
.confirm-modal .modal-close:focus-visible {
  color: var(--color-text);
}

/* Card */
.confirm-modal .modal-content {
  background-color: var(--color-white);
  border-radius: var(--radius-lg);
  padding: 30px;
  max-width: 500px;
  width: 90%;
  box-shadow: var(--shadow-md);
  text-align: center;
  max-height: 80vh;
  overflow-y: auto;
}

.confirm-modal .modal-content h3 {
  margin: 0 0 10px 0;
  font-size: var(--font-size-2xl);
  color: var(--color-text);
}

.confirm-modal .modal-content p {
  margin: 0 0 var(--space-5) 0;
  color: var(--color-text-secondary);
  font-size: var(--font-size-md);
  line-height: 1.6;
}

/* A dialog with something to fill in (ACC_Modal.choose with layout: 'form'):
   the title on the left with its × beside it, the content left-aligned, the
   buttons at the end. */
.confirm-modal .modal-content--form {
  text-align: left;
}

.confirm-modal .modal-content--form .modal-header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-3);
}

.confirm-modal .modal-content--form .modal-close {
  margin: calc(-1 * var(--space-1)) calc(-1 * var(--space-1)) 0 0;
}

.confirm-modal .modal-content--form .modal-buttons {
  justify-content: flex-end;
  margin-top: var(--space-5);
}

/* Icon (optional) */
.confirm-modal .modal-icon {
  margin-bottom: 20px;
}

.confirm-modal .modal-icon i {
  font-size: 48px;
  color: var(--color-warning);
}

/* Buttons */
.confirm-modal .modal-buttons {
  display: flex;
  gap: 15px;
  justify-content: center;
  flex-wrap: wrap;
}

/* Option list — tappable rows (one per choice): the family pickers and the
   event registrant selector. A row is a whole-row <button> when selectable,
   a <div class="modal-option--muted"> otherwise. The border, radius and
   padding are the choice-card look (components/_choice-card.css, ACC-2025
   D13). */
.modal-option-list {
  list-style: none;
  margin: 0 0 var(--space-4);
  padding: 0;
  text-align: left;
}

.modal-option-list li {
  margin-bottom: var(--space-2);
}

.modal-option-list .modal-option {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  width: 100%;
  font: inherit;
  text-align: left;
}

.modal-option-list .modal-option-selectable {
  cursor: pointer;
}

.modal-option-list .modal-option-selectable:not(:disabled):hover,
.modal-option-list .modal-option-selectable:focus-visible {
  border-color: var(--color-brand-green);
  background-color: var(--color-bg-subtle);
}

.modal-option-list .modal-option-selectable:disabled,
.modal-option-list .modal-option--muted {
  opacity: 0.65;
}

.modal-option-list .modal-option-selectable:disabled {
  cursor: not-allowed;
}

/* Tapped row while its request is in flight — keeps full opacity and its
   two-line height (sibling rows get the :disabled washout above, which this
   later equal-specificity rule overrides for the active row). */
.modal-option-list .modal-option.is-loading {
  opacity: 1;
  border-color: var(--color-brand-green);
  cursor: wait;
}

.modal-option-list .modal-option.is-loading .modal-option-chevron {
  font-size: var(--font-size-md);
}

.modal-option-list .modal-option-info {
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.modal-option-list .modal-option-name {
  font-weight: var(--font-weight-semibold);
  color: var(--color-text);
}

.modal-option-list .modal-option-state {
  font-size: var(--font-size-sm);
  color: var(--color-text-muted);
}

.modal-option-list .modal-option-chevron {
  flex-shrink: 0;
  color: var(--color-brand-green);
  font-size: var(--font-size-xl);
  line-height: 1;
}

/* Sticky footer for a long modal: the actions ride the bottom of the card so
   they stay reachable without scrolling to the end. Above a report table's
   sticky identity columns (z-index 1–2) so buttons are never overlaid. On a
   phone it sits at the end instead — a fixed bar costs too much of a small
   viewport and collides with the on-screen keyboard. */
.confirm-modal .modal-footer {
  position: sticky;
  bottom: 0;
  z-index: 3;
  padding: var(--space-4) var(--space-5);
  background-color: var(--color-white);
  border-top: 1px solid var(--color-border);
}
.confirm-modal .modal-footer:empty {
  display: none;
}

/* Responsive */
@media (max-width: 768px) {
  .confirm-modal .modal-footer {
    position: static;
  }

  .confirm-modal .modal-content {
    padding: var(--space-5);
    margin: 15px;
  }

  /* The main action on top, as in a sheet footer: it comes last in the
     markup (design-system.md, Dialog actions). */
  .confirm-modal .modal-buttons {
    flex-direction: column-reverse;
  }

  .confirm-modal .modal-buttons button {
    width: 100%;
  }
}

/* ACC-1770 — the address dialogs (address-utils.js). "Check your address":
   Google's suggestion and the address as entered, as two choice cards.
   "We couldn't verify this address": the entered address in a box. Either
   way an address is a few lines, with the parts in question highlighted. */
.acc-address-lines {
  display: block;
  line-height: 1.5;
}

.acc-address-lines > span {
  display: block;
}

/* In a card, an address reads as content, not as the card's small print. */
.choice-card .acc-address-lines {
  color: var(--color-text);
  font-size: var(--font-size-base);
}

.acc-address-flagged {
  background: var(--color-warning-bg);
  color: var(--color-warning-text);
  border-radius: var(--radius-sm);
  padding: 0 var(--space-1);
}

.acc-address-box {
  padding: var(--space-3) var(--space-4);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  background: var(--color-bg-subtle);
}

/* Google's terms: a Google suggestion shown outside a Google map carries
   "Google Maps", in exactly this font, size and colour, never translated. */
.choice-card .acc-address-credit {
  font-family: Roboto, sans-serif;
  font-size: var(--font-size-xs);
  color: var(--color-google-attribution);
}
/* ==========================================================================
   Choice cards (ACC-2025 D13)
   A radio (or checkbox) choice with room for a sentence: the whole card is
   the label, so the target is the card. Brand border and tint when chosen.

   <div class="choice-cards">
     <label class="choice-card">
       <input type="radio" name="…" value="…" />
       <span class="choice-card__title">Title</span>
       <span class="choice-card__desc">One sentence.</span>  (optional)
     </label>
   </div>

   .choice-cards--stack keeps one card per row (a short list in a modal);
   .choice-cards--compact tightens the cards for a longer list in a form;
   .choice-cards--3 puts three title-only cards in a row (two on a phone) for
   a long list of short options.
   Short yes/no radios stay plain inputs; this is for options that need
   explaining.
   ========================================================================== */

.choice-cards {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--space-3);
}

.choice-cards--stack {
  grid-template-columns: minmax(0, 1fr);
  gap: var(--space-2);
}

/* `display: grid` above outranks the browser's [hidden] rule (as on
   .info-box), so a list toggled with the attribute stayed visible. */
.choice-cards[hidden] {
  display: none;
}

@media (max-width: 560px) {
  .choice-cards {
    grid-template-columns: minmax(0, 1fr);
  }
}

/* The card look, shared with the one-tap rows of a modal option list
   (components/_modal.css). */
.choice-card,
.modal-option-list .modal-option {
  padding: 14px var(--space-4);
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-lg);
  background-color: var(--color-white);
  transition: border-color 0.15s ease, background-color 0.15s ease;
}

.choice-card {
  display: grid;
  grid-template-columns: 20px minmax(0, 1fr);
  /* Cards in a row share the tallest one's height; keep the title and its
     description together at the top rather than spread over it. */
  align-content: start;
  align-items: start;
  gap: var(--space-1) var(--space-3);
  margin: 0;
  color: var(--color-text);
  font-size: var(--font-size-base);
  font-weight: var(--font-weight-normal);
  line-height: 1.4;
  cursor: pointer;
}

.choice-card input {
  margin: 1px 0 0;
}

/* Title-only cards: a stacked list (e.g. a role picker in a modal), or
   three a row (--3, below). */
.choice-cards--stack .choice-card,
.choice-cards--3 .choice-card {
  align-items: center;
}

.choice-cards--stack .choice-card input,
.choice-cards--3 .choice-card input {
  margin: 0;
}

.choice-cards--stack .choice-card {
  padding: var(--space-3) 14px;
}

.choice-card__title {
  font-weight: var(--font-weight-semibold);
}

.choice-card__desc {
  grid-column: 2;
  color: var(--color-text-secondary);
  font-size: var(--font-size-md);
}

.choice-card:hover {
  border-color: var(--color-placeholder);
}

.choice-card:has(input:checked) {
  border-color: var(--color-brand-green);
  background-color: var(--color-brand-tint);
  box-shadow: inset 0 0 0 1px var(--color-brand-green);
}

/* The field disabled look (elements/_forms.css). Its own rule: a browser
   without :has() drops only this. */
.choice-card:has(input:disabled) {
  border-color: var(--color-border);
  background-color: var(--color-bg-subtle);
  color: var(--color-text-muted);
  cursor: not-allowed;
}

/* Compact: tighter cards for a longer list inside a form (the profile's
   email subscriptions). */
.choice-cards--compact {
  gap: var(--space-2);
}

.choice-cards--compact .choice-card {
  padding: var(--space-2) var(--space-3);
  gap: var(--space-1) var(--space-2);
  line-height: 1.3;
}

/* Three per row: title-only cards (the profile's interests). After the
   one-column rule above, so a phone gets two. */
.choice-cards--3 {
  grid-template-columns: repeat(3, minmax(0, 1fr));
}

.choice-cards--3 .choice-card {
  font-size: var(--font-size-md);
}

@media (max-width: 560px) {
  .choice-cards--3 {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .choice-cards--3 .choice-card {
    padding: var(--space-2);
  }
}

/* A required group that was skipped (.invalid-highlight on the fieldset). */
.invalid-highlight .choice-card {
  border-color: var(--color-danger);
}
/* ==========================================================================
   Multi-select (Custom Registration)
   Its JS wraps each <select multiple> in .custom-multi-wrapper: a field of
   chips (.custom-multi-display, which takes the field look from
   elements/_forms.css) opening a checkbox list styled like a themed select's
   open list. The native select stays in the wrapper, hidden, and carries the
   value.
   ========================================================================== */

.custom-multi-wrapper {
  position: relative;
}

.custom-multi-wrapper select[multiple] {
  display: none;
}

.custom-multi-display {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-1);
  height: auto;
  min-height: var(--control-height);
  padding: var(--space-1) 14px;
  cursor: pointer;
}

.custom-multi-display > div {
  padding: 2px var(--space-2);
  border-radius: var(--radius-pill);
  background-color: var(--color-navy);
  color: var(--color-white);
  font-size: var(--font-size-md);
}

.custom-multi-options {
  display: none;
  position: absolute;
  top: 100%;
  left: 0;
  right: 0;
  z-index: var(--z-dropdown);
  max-height: 200px;
  margin-top: 6px;
  padding: 6px;
  overflow-y: auto;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  background-color: var(--color-white);
  box-shadow: var(--shadow-md);
}

.custom-multi-wrapper.open .custom-multi-options {
  display: block;
}

/* Two classes: the host modules' own `form … label` spacing (0,1,1) loads
   after main.css. */
.custom-multi-wrapper .custom-multi-options label {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 0;
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-md);
  font-weight: var(--font-weight-normal);
  cursor: pointer;
}

.custom-multi-wrapper .custom-multi-options label:hover {
  background-color: var(--color-brand-tint);
}
/* ==========================================================================
   Record Sheet Component
   Shared shell for action-based table rows (docs/record-sheet.md):
   centered dialog on desktop, ~93% bottom sheet on mobile, with an internal
   view stack. Driven by src/js/utils/record-sheet.js.
   Portal-hosted pages only — embedded modules need a scoped copy.
   ========================================================================== */

.record-sheet {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.45);
  z-index: var(--z-modal);
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.25s ease, visibility 0.25s ease;
}

.record-sheet.active {
  opacity: 1;
  visibility: visible;
  /* Opening: visible at once, so open() can move focus into the dialog in the
     same task. Closing still fades, through the base rule's transition. */
  transition: opacity 0.25s ease, visibility 0s;
}

/* Applied to the html element by record-sheet.js while a sheet is open —
   the component owns its scroll lock rather than borrowing another one's.
   (Spelling out "html element": a literal angle-bracket tag in a comment
   makes HubSpot's upload validator reject the whole file as HTML.) */
.record-sheet-lock {
  overflow-y: hidden;
}

/* Panel — desktop: centered dialog. The view stack inside is absolutely
   positioned, so the panel needs an EXPLICIT height at every breakpoint;
   max-height alone collapses the flex body to a bare header. */
.record-sheet-panel {
  position: absolute;
  left: 50%;
  top: 48px;
  transform: translateX(-50%);
  /* 760 (was 640): the Guests slot grid earns the extra room — bands keep
     name + email + controls on one line further down the breakpoints. */
  width: min(760px, calc(100% - 48px));
  height: min(680px, calc(100vh - 96px));
  height: min(680px, calc(100dvh - 96px));
  background: var(--color-white);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-md);
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

.record-sheet-grab {
  display: none;
  width: 40px;
  height: 4px;
  border-radius: 2px;
  background: var(--color-border-strong);
  margin: 8px auto 0;
  flex-shrink: 0;
}

/* Mobile: ~93% bottom sheet with grab handle — deliberately not full-screen
   (the dimmed sliver of page behind preserves spatial context). */
@media only screen and (max-width: 768px) {
  .record-sheet-panel {
    left: 0;
    top: auto;
    bottom: 0;
    transform: none;
    width: 100%;
    height: 93vh;
    height: 93dvh;
    border-radius: 18px 18px 0 0;
  }

  .record-sheet-grab {
    display: block;
  }
}

/* Header */
.record-sheet-head {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 14px 16px;
  border-bottom: 1px solid var(--color-border);
  flex-shrink: 0;
}

/* Bare arrow — no pill. */
.record-sheet-back {
  display: none;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  color: var(--color-navy);
  font-size: var(--font-size-lg);
  line-height: 1;
  cursor: pointer;
  flex-shrink: 0;
}

.record-sheet-back:hover {
  color: var(--color-brand-green-dark);
}

.record-sheet-panel.in-subview .record-sheet-back {
  display: inline-flex;
}

.record-sheet-titles {
  flex: 1;
  min-width: 0;
}

.record-sheet-title {
  margin: 0;
  font-size: var(--font-size-md);
  color: var(--color-navy);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.record-sheet-sub {
  font-size: var(--font-size-xs);
  color: var(--color-text-secondary);
}

.record-sheet-close {
  font-size: var(--font-size-2xl);
  line-height: 1;
  color: var(--color-text-muted);
  cursor: pointer;
  flex-shrink: 0;
}

.record-sheet-close:hover {
  color: var(--color-text);
}

/* Footer — for a sheet whose view is a form: its actions stay in reach while
   the view scrolls. A sibling of .record-sheet-views, so a popover scrolled
   into view inside the form never lands under it. */
.record-sheet-foot {
  display: flex;
  justify-content: flex-end;
  gap: var(--space-3);
  padding: var(--space-3) var(--space-4);
  border-top: 1px solid var(--color-border);
  background: var(--color-white);
  flex-shrink: 0;
}

/* Phones: full-width buttons, primary on top. Side by side, French labels
   ("Enregistrer les modifications") wrapped and clipped. */
@media only screen and (max-width: 768px) {
  .record-sheet-foot {
    flex-direction: column-reverse;
    gap: var(--space-2);
  }

  .record-sheet-foot > .btn {
    width: 100%;
  }
}

/* View stack — one level deep: home view ⟷ sub-views */
.record-sheet-views {
  flex: 1;
  position: relative;
  overflow: hidden;
}

.record-sheet-view {
  position: absolute;
  inset: 0;
  overflow-y: auto;
  padding: 18px 20px 28px;
  background: var(--color-white);
  transform: translateX(100%);
  transition: transform 0.28s ease;
}

.record-sheet-view.is-current {
  transform: translateX(0);
}

.record-sheet-view.is-left {
  transform: translateX(-28%);
}

/* record-sheet.js adds .no-anim for instant view swaps on open() — one
   container class + one layout flush instead of per-view inline styles. */
.record-sheet-views.no-anim .record-sheet-view {
  transition: none;
}

@media (prefers-reduced-motion: reduce) {
  .record-sheet-view {
    transition: none;
  }
}

/* Sheet furniture shared by adopting tables: section headings, summary lines,
   the navigate-to-a-sub-view "trip action" row (status line + chevron), and the
   status-chip group wrapper (chips themselves are plain text separated by
   middots). Locked design decisions — docs/record-sheet.md §2. */
/* Every section heading in the sheet, whether the sheet renders it or it
   comes from HubDB rich text. The rule above it is what separates one section
   from the next — without it the sections ran together in one scroll and it
   wasn't obvious where "Trip details" ended and the hut's own content began. */
.sheet-section-title {
  margin: var(--space-5) 0 var(--space-2);
  padding-top: var(--space-4);
  border-top: 1px solid var(--color-border);
  font-size: var(--font-size-md);
  font-weight: var(--font-weight-bold);
  text-transform: uppercase;
  letter-spacing: 0.03em;
  color: var(--color-navy);
}

/* The quiet line under a section title — what the section is for. */
.sheet-section-help {
  margin: 0 0 var(--space-3);
  font-size: var(--font-size-sm);
  line-height: 1.5;
  color: var(--color-text-secondary);
}

/* One "label … value" line of a summary: the label in a strong element, the
   values after it. */
.sheet-line {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2);
  flex-wrap: wrap;
  padding: var(--space-2) 0;
  border-bottom: 1px solid var(--color-bg-muted);
  font-size: var(--font-size-md);
  color: var(--color-text-secondary);
}

.sheet-line strong {
  color: var(--color-text);
}

/* The first heading has nothing above it to be separated from. */
.sheet-section-title:first-child {
  margin-top: 0;
  padding-top: 0;
  border-top: 0;
}

/* Re-assert for HubDB sections: each of those headings IS the first child of
   its own <section>, so the rule above would strip the divider from every one
   of them and collapse the hut content back into a single run. Same
   specificity as that rule, declared after it, so this wins — deliberately,
   and it has to stay below it. A form sheet's later fieldsets (Update
   Details: Spouse, Children) open the same way. */
.hut-content-section > .sheet-section-title,
.record-sheet-view fieldset ~ fieldset > .sheet-section-title {
  margin-top: var(--space-5);
  padding-top: var(--space-4);
  border-top: 1px solid var(--color-border);
}

.trip-action-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  width: 100%;
  text-align: left;
  background: var(--color-white);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  padding: 12px 14px;
  margin-top: var(--space-2);
  cursor: pointer;
  font: inherit;
}

.trip-action-row:hover,
.trip-action-row:focus {
  background: var(--color-brand-tint);
  border: 1px solid var(--color-brand-green);
  border-radius: var(--radius-md);
}

/* A finished trip's rows stay navigable — the roster is still worth reading —
   but drop the invitation to act on something that can no longer be changed
   (ACC-1708 review item 6). */
.trip-action-row--past {
  background: var(--color-bg-subtle);
  color: var(--color-text-secondary);
}

/* An item that is still owed looks owed. */
.trip-action-row--todo {
  border-color: var(--color-warning);
  background: var(--color-warning-bg);
}

.trip-action-row--todo .trip-action-info > strong {
  color: var(--color-warning-text);
}

.todo-flag {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  color: var(--color-warning-text);
  font-weight: var(--font-weight-semibold);
}

.trip-actions-past {
  margin: var(--space-2) 0 0;
  font-size: var(--font-size-md);
  color: var(--color-text-muted);
}

/* flex: 1 so the info block absorbs the spare width and the chip lands in the
   same place on every row. Under space-between alone the chip's position was
   set by how long that row's text happened to be, so a short row ("Guests")
   and a long one ("Emergency details / Contact: …") put their chips at
   different x. */
.trip-action-info {
  min-width: 0;
  flex: 1;
}

/* A chip COLUMN, not just a right edge. Letting the chips size themselves
   aligned their right edges but left their left edges ragged, because
   "Action needed" is much wider than "Added". A min-width sized to the
   longest label (French runs longer than English) gives every chip the same
   starting x, so the rows read as a column. */
.trip-action-row > .status-pills {
  flex: 0 0 auto;
  justify-content: flex-start;
  min-width: 9.5rem;
}

/* Drop the reserved chip column on a phone: the row needs every pixel for
   its own text, and one chip per row has nothing to line up against. This
   MUST come after the rule above — same selector, so it wins on source order
   alone. It first lived in the early 768px block and silently lost the tie,
   leaving a 171px column that squeezed "Member validation" into three lines. */
@media only screen and (max-width: 768px) {
  .trip-action-row > .status-pills {
    min-width: 0;
  }
}

.trip-action-info strong {
  display: block;
  color: var(--color-navy);
}

.trip-action-info > span {
  display: block;
  margin-top: 2px;
  font-size: var(--font-size-md);
  color: var(--color-text-secondary);
}

.trip-action-chev {
  color: var(--color-text-muted);
  font-size: 1.2em;
  flex-shrink: 0;
}

.status-chips {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-1);
  font-size: var(--font-size-md);
  color: var(--color-text-secondary);
}

.status-chips .status-chip + .status-chip::before {
  content: '\00b7';
  margin: 0 var(--space-1);
  color: var(--color-text-muted);
}

/* Row actions (status pills group). The action buttons themselves live in
   components/_row-actions.css so My Hut Bookings and Staffed Trips share one
   definition — .row-quick-action / .row-open-btn are behaviour hooks only. */
.status-pills {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  flex-wrap: wrap;
}
/* ==========================================================================
   Row actions (ACC-1708)
   Shared action buttons for the portal's record tables — My Hut Bookings,
   Staffed Trips, and any table that adopts the record-sheet pattern next.

   Why this file exists: the quick action used to be built with
   --radius-pill, the same token as .status-pill, so it rendered as the
   same shape as the status chips sitting beside it in the next column and
   read as a chip rather than a control. The rule these classes encode:

       chips use --radius-pill · buttons use --radius-button

   One primary action per row (filled) and one secondary (outlined), so the
   hierarchy is legible at a glance down the column.
   ========================================================================== */

/* Shape, size (32px) and the primary / secondary colours are shared with
   the small button (.btn--sm) in elements/_buttons.css. Only the row
   specifics live here. */
.acc-row-btn {
  line-height: 1.3;
  white-space: nowrap;
}

/* A truncating label (Staffed Trips' report names run long and are nowrap)
   needs an explicit shrink, or it pushes the button out of its column.

   CONTRACT: wrap the label text in a child <span>. The ellipsis rule below
   targets that span — apply --block to a button whose label is a bare text
   node and you get silent overflow instead of truncation. */
.acc-row-btn--block {
  width: 100%;
  min-width: 0;
  max-width: 100%;
  justify-content: flex-start;
  text-align: left;
}

.acc-row-btn--block > span {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
}

.acc-row-btn > i {
  flex-shrink: 0;
}

/* Icon-only. Its label lives in aria-label/title, so it must never be the
   only way to reach something a text button couldn't also offer. */
.acc-row-btn--icon {
  padding: 0 var(--space-2);
}

/* On a phone a long label (French, mostly) wraps inside its button rather
   than pushing it past the row's edge. It only changes a label wider than
   the row. --block truncates instead, by design. */
@media (max-width: 768px) {
  .acc-row-btn:not(.acc-row-btn--block) {
    max-width: 100%;
    white-space: normal;
    text-align: center;
  }
}
/* Shared module container and header — light variant.
   Used as the standard portal module wrapper across most modules.
   Module-specific h3s outside this component (e.g. Availability Calendar)
   should opt into --module-heading-size for visual consistency.
*/

:root {
  --module-heading-size: 22px;
}

.module-card {
  background: var(--color-white);
  border-radius: var(--radius-button);
}

.module-header {
  padding: 15px 25px;
  border-bottom: 1px solid var(--color-bg-muted);
}

.module-header h3 {
  font-size: var(--module-heading-size);
  color: var(--color-brand-green);
  margin: 0;
}

/* Phones: one narrow side padding inside every module, so a phone's width
   goes to content without text running into the card's edge. The header
   takes it here; a module body takes it by writing its padding as
   `padding: <y> var(--module-pad-x, <x>)`, <x> being its side padding
   everywhere else. Boxes inside a body (cards, grey form panels) keep
   their own inner padding. */
@media only screen and (max-width: 768px) {
  :root {
    --module-pad-x: 15px;
  }

  .module-header {
    padding-left: var(--module-pad-x);
    padding-right: var(--module-pad-x);
  }
}

.module-header > div {
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
  justify-content: space-between;
  align-items: center;
  gap: 15px;
}

/* Optional lead paragraph under a module's title — what the page is for, and
   why it asks for what it asks for. */
/* Sits as a sibling of the title row, not inside it — see the note in My Hut
   Bookings' module.html. Inside that wrapping flex row it would shrink to fit
   beside the heading rather than drop below it. */
.module-intro {
  margin: var(--space-2) 0 0;
  /* Full width, by request. A readable-measure cap was tried twice (78ch,
     then 92ch) and both read as the paragraph stopping halfway across a wide
     module — the visual cost outweighed the line-length benefit here. */
  font-size: var(--font-size-sm);
  line-height: 1.5;
  color: var(--color-text-secondary);
}

/* Sub-section heading inside a module body — uppercase green group label
   used to cluster related info rows (e.g. Membership / Dates / Waiver). */
.info-group-heading {
  margin: var(--space-5) 0 6px;
  font-size: var(--font-size-md);
  font-weight: var(--font-weight-semibold);
  text-transform: uppercase;
  letter-spacing: 0.5px;
  color: var(--color-brand-green);
  display: flex;
  align-items: center;
  gap: var(--space-2);
}

.info-group-heading i {
  font-size: var(--font-size-md);
  flex-shrink: 0;
}

.info-group-heading:first-of-type {
  margin-top: 0;
}
/* Language Switcher
   Shared EN | FR toggle used by the Portal Header and the registration flow.
   Markup comes from the lang_switcher() macro in src/macros/header-macros.html. */

.header__language-switcher {
  display: flex;
  align-items: center;
  gap: var(--space-1);
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-semibold);
  margin-right: 4px;
}

.lang-option {
  color: var(--color-brand-green);
  text-decoration: none;
  padding: 2px var(--space-1);
  border-radius: var(--radius-sm);
  opacity: 0.6;
  transition: opacity 0.2s;
}

.lang-option:hover {
  opacity: 1;
}

.lang-option.lang-active {
  opacity: 1;
  background: var(--color-brand-tint);
}

.lang-divider {
  color: var(--color-brand-green);
  opacity: 0.4;
}
/* ==========================================================================
   Tester Banner Component
   Shared test mode banner used across lottery and booking modules
   ========================================================================== */

.tester-banner {
  background-color: var(--color-info-bg);
  border: 1px solid var(--color-info-cyan);
  border-radius: var(--radius-md);
  padding: var(--space-3) var(--space-4);
  margin-bottom: 20px;
  display: flex;
  align-items: center;
  gap: var(--space-3);
  flex-wrap: wrap;
}

.tester-text {
  font-size: var(--font-size-md);
  color: var(--color-info-text);
}
/* ==========================================================================
   Centered Page Container
   Shared layout for standalone pages (logout, registration complete)
   ========================================================================== */

.page-branding img {
  width: 200px;
  display: block;
  margin: 0 auto;
}

.container {
  width: 450px;
  text-align: center;
  padding-top: 40px;
  padding-left: 20px;
  padding-right: 20px;
}
.container-parent {
  display: flex;
  justify-content: center;
  align-items: center;
}
/* ==========================================================================
   Module Loader Component
   Shared inline loading state used across multiple modules
   ========================================================================== */

.module-loader {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: var(--space-10) var(--space-5);
  width: 100%;
}

.module-loader.hidden {
  display: none;
}

/* Spinner used inside .module-loader (also reused by Alpine Loader.module's
   full-page overlay). Animated SVG circle with the ACC logo centered over it. */
.preloader {
  position: relative;
  width: 150px;
  height: 150px;
}

.preloader svg {
  width: 150px;
  height: 150px;
  animation: preloader-rotate 2s linear infinite;
}

.preloader circle {
  fill: none;
  /* Brand spinner, not a success state — keep it ACC green (was #2e7d32,
     which the audit folded to --color-success; too light next to the logo). */
  stroke: var(--color-brand-green);
  stroke-width: 4;
  stroke-linecap: round;
  stroke-dasharray: 80 200;
  stroke-dashoffset: 0;
  animation: preloader-dash 1.5s ease-in-out infinite;
}

.preloader img {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 40px;
  height: 40px;
  transform: translate(-50%, -50%);
  border-radius: 0%;
}

/* Inside a module the spinner is compact, so a loading list or table is about
   the height of a short list (.time-badge-loader is Achievement Badges' own
   wrapper). Other loaders keep the large one. */
.module-loader .preloader,
.module-loader .preloader svg,
.time-badge-loader .preloader,
.time-badge-loader .preloader svg {
  width: 80px;
  height: 80px;
}

.module-loader .preloader img,
.time-badge-loader .preloader img {
  width: 28px;
  height: 28px;
}

@keyframes preloader-rotate {
  100% {
    transform: rotate(360deg);
  }
}

@keyframes preloader-dash {
  0% {
    stroke-dasharray: 1, 200;
    stroke-dashoffset: 0;
  }
  50% {
    stroke-dasharray: 100, 100;
    stroke-dashoffset: -15;
  }
  100% {
    stroke-dasharray: 1, 200;
    stroke-dashoffset: -125;
  }
}
/* ==========================================================================
   Empty State
   Shared "nothing to show here" layout — used when a module has no items
   to display (e.g. no sections, no transactions, no open lotteries).
   Pattern: centered icon + h4 + supporting copy, optional CTA.
   ========================================================================== */

.empty-state {
  text-align: center;
  padding: var(--space-10) var(--space-5);
}

.empty-state .message-icon {
  margin-bottom: 20px;
}

.empty-state .message-icon i {
  font-size: 64px;
  color: var(--color-text-muted);
}

.empty-state h4 {
  margin: 0 0 10px;
}

.empty-state p {
  margin: 0 auto;
  max-width: 480px;
  color: var(--color-text-secondary);
}

/* The optional CTA row: a primary action and/or a plain link, stacked and
   centred under the copy. */
.empty-state__actions {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-3);
  margin-top: var(--space-5);
}
/* ==========================================================================
   Profile Avatar (ACC-1936)
   Circular member photo with an initials fallback. Rendered server-side by the
   profile_avatar() macro (src/macros/general-macros.html) and client-side by
   renderAvatarInto() in the Update Personal Information module.

   Every caller sets its own size by overriding --acc-avatar-size (header 35px,
   profile page 96px, compact family rows 56px) — no size modifiers here.
   ========================================================================== */

.acc-avatar {
  --acc-avatar-size: 48px;

  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 auto;
  width: var(--acc-avatar-size);
  height: var(--acc-avatar-size);
  border-radius: var(--radius-circle);
  overflow: hidden;
  background: var(--color-brand-green);
  color: var(--color-white);
  font-weight: var(--font-weight-semibold);
  line-height: 1;
  user-select: none;
}

.acc-avatar-img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.acc-avatar-initials {
  /* Scales with the circle so one rule covers every call site. */
  font-size: calc(var(--acc-avatar-size) * 0.4);
  letter-spacing: 0.5px;
}
/* Optional child email — parent/guardian acknowledgement (ACC-1858)

   The consent row sits INSIDE the child card, directly under that child's
   email field, and is hidden until that email is filled in (toggled live by
   updateChildEmailConsentState in both modules). One per child: it attests to
   one address, so it belongs beside it — a shared box at the foot of the list
   read as unrelated to the field that summoned it, and appearing down there
   shifted the page while the parent was still typing.

   Shared rather than per-module: Update Personal Information and Custom
   Registration render the same markup, and this control gates a consent
   record — a place where two copies drifting apart is a compliance problem,
   not a cosmetic one. */
.child-email-consent {
  margin-top: var(--space-3);
  padding-top: var(--space-3);
  border-top: 1px solid var(--color-border);
}

.child-email-consent label {
  display: flex;
  align-items: flex-start;
  gap: var(--space-2);
  cursor: pointer;
}

.child-email-consent input[type='checkbox'] {
  margin-top: 3px;
}

/* A child already on file is marked for removal rather than deleted outright —
   the confirmation happens once, at save, which is the point of no return
   (ACC-1858). The card stays on screen so the names in that dialog match what
   the parent is looking at, and the pending state is visible rather than
   implied. A child with no id was never saved, so it just goes and never
   reaches this state.

   The dimming is applied to the FIELDS, never to the whole card: opacity
   creates a stacking context its children can't climb back out of, so dimming
   the card greyed out the Undo control too and made the one thing still worth
   clicking look disabled. */
.child-form-wrapper.pending-removal
  .child-form
  > *:not(.child-title):not(.pending-removal-note) {
  opacity: 0.5;
}

.child-form-wrapper.pending-removal .pending-removal-note {
  margin: var(--space-3) 0 0;
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-semibold);
  color: var(--color-danger);
}

/* Undo restores — it isn't destructive, so it drops the danger red the Remove
   control wears and reads as a plain, clearly-live action. */
.child-form-wrapper.pending-removal .child-title a.remove-child {
  background: var(--color-bg-muted);
  color: var(--color-text);
  border: 1px solid var(--color-border-strong);
}

.child-form-wrapper.pending-removal .child-title a.remove-child:hover {
  background: var(--color-border);
}

/* Utilities
Helper classes with ability to override anything that comes before it
*/

/* Hide elements */
.hidden {
  display: none !important;
}

/* For content that needs to be visually hidden but stay visible for screenreaders */

.show-for-sr {
  border: 0 !important;
  clip: rect(0, 0, 0, 0) !important;
  height: 1px !important;
  overflow: hidden !important;
  padding: 0 !important;
  position: absolute !important;
  white-space: nowrap !important;
  width: 1px !important;
}

@media (max-width: 767px) {
  .show-for-sr--mobile {
    border: 0 !important;
    clip: rect(0, 0, 0, 0) !important;
    height: 1px !important;
    overflow: hidden !important;
    padding: 0 !important;
    position: absolute !important;
    white-space: nowrap !important;
    width: 1px !important;
  }
}