/* ==========================================================================
   Daraan Assisted Living: Design System
   Conroe, TX · Residential Care Home (Type B licence pending)
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. TOKENS
   -------------------------------------------------------------------------- */
:root {
  /* ---- GROUNDS: a paper ladder, not one flat cream ------------------------
     Nothing on this site is pure white. Pure white against warm brand
     colours reads clinical, and it is the single strongest institutional
     signal there is. Sections step through this ladder so the page has
     rhythm instead of alternating cream/white. */
  --paper-0: #FDFBF6;   /* lightest, replaces every former pure-white surface */
  --paper-1: #F8F3E9;   /* the default body ground */
  --paper-2: #F2EBDD;
  --paper-3: #EAE0CD;
  --paper-4: #DED2BA;   /* deepest paper, for a heavy band */

  /* ---- INK: all warm, all measured against --paper-1 ---------------------- */
  --ink:       #22282A;  /* 13.5:1  headings */
  --ink-body:  #454B48;  /*  8.1:1  body copy */
  --ink-soft:  #5C5349;  /*  7.0:1  secondary text. Replaces the old --muted,
                                    which sat at 4.46:1 and failed AA. */
  --rule:      #8B8172;  /*  3.6:1  hairlines that do real work (form borders) */
  --rule-soft: #C9BFA8;  /*         decorative separators only */

  /* ---- BRAND, text-safe ---------------------------------------------------
     Warmth lives in the hue and in the background. Contrast lives in the
     text. These three are dark enough to read. */
  --forest-900: #1F3B2C;
  --forest-800: #264936;
  --forest-700: #2D5440;   /* 7.7:1  links and headings */
  --forest-600: #3A6B52;
  --forest-500: #4A8065;
  --clay-ink:   #8C4226;   /* 6.7:1  inline links, small terracotta text */
  --sage-ink:   #47563F;   /* 7.3:1  sage dark enough to carry type */

  /* ---- BRAND, surface only. Never set text in these. ----------------------
     --sage-500 is 2.8:1 on paper. It cannot carry text and cannot serve as a
     meaningful border. It is a surface colour and nothing else. */
  --sage-500:  #7A9B6A;
  --sage-300:  #A8C39A;
  --sage-200:  #C6DBB9;
  --sage-100:  #E2EDDB;
  --sage-50:   #F0F5EC;
  --clay-600:  #A9552F;    /* 5.2:1 with white on top, so button fills are fine */
  --clay-500:  #B96A44;
  --clay-100:  #F6E7DE;
  --tan:       #C9B890;

  /* Status */
  --good: #2D7A52;
  --warn: #8C4226;

  /* ---- ELEVATION ----------------------------------------------------------
     Layered, and hue-matched to the warm ground. A pure-black shadow
     desaturates the paper beneath it, which is exactly what makes uniform
     card shadows read as generic. One light source, upper-left. */
  --shadow-hue: 30deg 30% 32%;
  --sh-sm: 0.5px 1px 1.5px hsl(var(--shadow-hue) / 0.30);
  --sh-md:
    1px 2px 2px hsl(var(--shadow-hue) / 0.16),
    2px 4px 4px hsl(var(--shadow-hue) / 0.16),
    3px 6px 6px hsl(var(--shadow-hue) / 0.16);
  --sh-lg:
    1px 2px 2px   hsl(var(--shadow-hue) / 0.10),
    2px 4px 4px   hsl(var(--shadow-hue) / 0.10),
    4px 8px 8px   hsl(var(--shadow-hue) / 0.10),
    8px 16px 16px hsl(var(--shadow-hue) / 0.10);

  /* ---- GEOMETRY -----------------------------------------------------------
     Committed positions rather than four middling radii. Photographs in a
     house have square corners; only the buttons are pills. */
  --r-plate: 0;        /* photos, panels, quote blocks */
  --r-input: 4px;      /* form fields, for affordance */
  --r-pill: 999px;     /* buttons only */
  --nav-h: 76px;

  /* ---- MOTION -------------------------------------------------------------
     One easing curve, reused everywhere. Variety of motion is what breaks
     the calm. No spring or overshoot: bouncy reads unserious here. */
  --ease: cubic-bezier(0.165, 0.84, 0.44, 1);
  --dur-fast: 150ms;
  --dur: 280ms;
  --dur-slow: 420ms;

  /* Rhythm */
  --sp-section: clamp(4rem, 8vw, 7rem);
  --container: 1180px;

  /* ---- TYPE ---------------------------------------------------------------
     Three roles, not two. The monospace carries metadata: prices, times, the
     licence number, photo captions. It is what makes the page read like a
     record of a real house rather than a template. */
  --f-display: 'Playfair Display', Georgia, 'Times New Roman', serif;
  --f-body: 'DM Sans', -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif;
  --f-mono: 'DM Mono', ui-monospace, 'SF Mono', Menlo, Consolas, monospace;

  /* Fluid scale. Every step keeps a rem term so browser zoom still works;
     pure vw type is a documented WCAG 1.4.4 failure. Body sits at 19-21px:
     GOV.UK and the NHS both ship 19px and dropped 14px from their scale. */
  --step--1: clamp(1rem,      0.970rem + 0.13vw, 1.0625rem);  /* 16 → 17 */
  --step-0:  clamp(1.1875rem, 1.134rem + 0.22vw, 1.3125rem);  /* 19 → 21 */
  --step-1:  clamp(1.5rem,    1.341rem + 0.67vw, 1.875rem);   /* 24 → 30 */
  --step-2:  clamp(1.875rem,  1.557rem + 1.33vw, 2.625rem);   /* 30 → 42 */
  --step-3:  clamp(2.25rem,   1.614rem + 2.67vw, 3.75rem);    /* 36 → 60 */

  /* ---- LEGACY ALIASES -----------------------------------------------------
     Old token names still referenced further down the file and in inline
     styles across the PHP pages. Kept pointing at the new values so nothing
     breaks; retire them as each page is rebuilt. */
  --cream:     var(--paper-1);
  --cream-200: var(--paper-2);
  --cream-300: var(--paper-3);
  --white:     var(--paper-0);
  --body:      var(--ink-body);
  --muted:     var(--ink-soft);
  --line:      var(--rule-soft);
  --r-sm: var(--r-input);
  --r:    var(--r-plate);
  --r-lg: var(--r-plate);
  --r-xl: var(--r-plate);
}

/* --------------------------------------------------------------------------
   2. RESET / BASE
   -------------------------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }

html {
  scroll-behavior: smooth;
  scroll-padding-top: calc(var(--nav-h) + 16px);
  -webkit-text-size-adjust: 100%;
}

body {
  margin: 0;
  font-family: var(--f-body);
  font-size: var(--step-0);  /* 19 → 21px. 17px was too small for this audience. */
  line-height: 1.6;
  color: var(--ink-body);
  background: var(--paper-1);
  -webkit-font-smoothing: antialiased;
  /* NOTE: no `overflow-x: hidden` here on purpose. On body it can turn the
     page into a scroll container and break `position: sticky` on the header
     in Safari and older Chrome. Horizontal overflow is instead prevented at
     source, with `overflow-x: clip` as a safety net in section 18 (clip does
     not create a scroll container, so sticky keeps working). */
}

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

h1, h2, h3, h4 {
  font-family: var(--f-display);
  color: var(--forest-900);
  font-weight: 600;
  line-height: 1.15;
  letter-spacing: -0.015em;
  margin: 0 0 .6em;
}

/* Lower clamp minimums so headings never outgrow a 320px screen. */
h1 { font-size: clamp(2.05rem, 5.4vw, 3.9rem); }
h2 { font-size: clamp(1.7rem, 3.9vw, 2.85rem); }
h3 { font-size: clamp(1.2rem, 2.2vw, 1.6rem); }
h4 { font-size: 1.1rem; }

p { margin: 0 0 1.15rem; }
p:last-child { margin-bottom: 0; }

a { color: var(--forest-700); text-decoration-thickness: 1px; text-underline-offset: 3px; }
a:hover { color: var(--clay-600); }

em.accent {
  font-style: italic;
  color: var(--clay-600);
}

strong { color: var(--forest-900); font-weight: 600; }

hr { border: 0; border-top: 1px solid var(--line); margin: 2.5rem 0; }

/* Accessibility */
:focus-visible {
  outline: 3px solid var(--clay-500);
  outline-offset: 3px;
  border-radius: 4px;
}

.skip-link {
  position: absolute; left: 8px; top: -60px;
  background: var(--forest-700); color: var(--paper-0);
  padding: .75rem 1.25rem; border-radius: 0 0 var(--r-sm) var(--r-sm);
  z-index: 2000; font-weight: 600; text-decoration: none;
  transition: top .18s;
}
.skip-link:focus { top: 0; color: var(--paper-0); }

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

/* --------------------------------------------------------------------------
   3. LAYOUT
   -------------------------------------------------------------------------- */
.container {
  width: min(100% - 2.5rem, var(--container));
  margin-inline: auto;
}
.container--narrow { width: min(100% - 2.5rem, 820px); margin-inline: auto; }

.section { padding-block: var(--sp-section); }
.section--tight { padding-block: clamp(2.5rem, 5vw, 4rem); }
.section--cream { background: var(--cream); }
.section--white { background: var(--paper-0); }
.section--sage  { background: var(--sage-50); }
.section--forest {
  /* The light end was --forest-600, against which the secondary text on this
     band (#CFDDCE, --sage-200) measured 4.37:1 and 4.18:1 and failed AA.
     Ending on --forest-700 lifts them to 6.07:1 and 5.80:1. */
  background: linear-gradient(160deg, var(--forest-800), var(--forest-700));
  color: #E9F0E9;
}
.section--forest h2, .section--forest h3 { color: var(--paper-0); }

.eyebrow {
  display: inline-block;
  font-size: .78rem;
  font-weight: 600;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--clay-600);
  margin-bottom: .9rem;
}
.section--forest .eyebrow { color: var(--sage-200); }

.section-head { max-width: 720px; margin-bottom: clamp(2.2rem, 4vw, 3.2rem); }
.section-head.center { margin-inline: auto; text-align: center; }
.section-head p { font-size: 1.1rem; color: var(--muted); }
.section--forest .section-head p { color: #CFDDCE; }

.lead { font-size: clamp(1.1rem, 1.9vw, 1.28rem); line-height: 1.65; color: var(--body); }

/* Grids */
.grid { display: grid; gap: 1.5rem; }
.grid-2 { grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); }
.grid-3 { grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); }
.grid-4 { grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); }

.split {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: clamp(2rem, 5vw, 4.5rem);
  align-items: center;
}
@media (max-width: 860px) { .split { grid-template-columns: 1fr; } }

/* --------------------------------------------------------------------------
   4. BUTTONS
   -------------------------------------------------------------------------- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  /* Belt and braces: centring above depends on the element staying a flex
     container. text-align keeps the label centred even if another rule
     changes `display`, which is exactly how the tel: bug went unnoticed. */
  text-align: center;
  gap: .55rem;
  min-height: 52px;
  padding: .85rem 1.75rem;
  border-radius: 100px;
  border: 2px solid transparent;
  font-family: var(--f-body);
  font-size: 1.02rem;
  font-weight: 600;
  line-height: 1.2;
  text-decoration: none;
  cursor: pointer;
  transition: transform .18s ease, box-shadow .18s ease, background .18s ease, color .18s ease;
}
.btn:hover { transform: translateY(-2px); }
.btn:active { transform: translateY(0); }

.btn--primary {
  background: var(--clay-600);
  color: var(--paper-0);
  box-shadow: 0 6px 20px rgba(169, 85, 47, .28);
}
.btn--primary:hover { background: var(--clay-500); color: var(--paper-0); box-shadow: 0 10px 30px rgba(169, 85, 47, .36); }

.btn--forest { background: var(--forest-700); color: var(--paper-0); box-shadow: 0 6px 20px rgba(45, 84, 64, .25); }
.btn--forest:hover { background: var(--forest-600); color: var(--paper-0); }

.btn--ghost {
  background: transparent;
  color: var(--forest-700);
  border-color: var(--forest-600);
}
.btn--ghost:hover { background: var(--forest-700); color: var(--paper-0); }

.btn--light { background: var(--paper-0); color: var(--forest-800); }
.btn--light:hover { background: var(--cream-200); color: var(--forest-900); }

.btn--outline-light { background: transparent; color: var(--paper-0); border-color: rgba(255,255,255,.55); }
.btn--outline-light:hover { background: var(--paper-0); color: var(--forest-800); }

.btn--lg { min-height: 60px; padding: 1rem 2.25rem; font-size: 1.1rem; }
.btn--block { width: 100%; }

.btn-row { display: flex; flex-wrap: wrap; gap: .9rem; }
.btn-row.center { justify-content: center; }

/* --------------------------------------------------------------------------
   5. HEADER / NAV
   -------------------------------------------------------------------------- */
.site-header {
  position: sticky;
  top: 0;
  z-index: 1000;
  background: rgba(248, 243, 233, .93);
  backdrop-filter: saturate(160%) blur(12px);
  -webkit-backdrop-filter: saturate(160%) blur(12px);
  border-bottom: 1px solid var(--line);
}
.site-header.is-scrolled { box-shadow: var(--sh-sm); }

.nav {
  height: var(--nav-h);
  display: flex;
  align-items: center;
  gap: 1.25rem;
}

.brand {
  display: flex; align-items: center; gap: .6rem;
  text-decoration: none; flex-shrink: 0; margin-right: auto;
}
.brand img { width: 44px; height: 44px; border-radius: 50%; }
.brand-name { display: flex; flex-direction: column; line-height: 1.1; }
.brand-name b {
  font-family: var(--f-display);
  font-size: 1.22rem; font-weight: 600; color: var(--forest-800);
  letter-spacing: -.01em;
}
.brand-name span {
  font-size: .66rem; letter-spacing: .18em; text-transform: uppercase;
  color: var(--sage-ink); font-weight: 600;
}

.nav-links { display: flex; align-items: center; gap: .15rem; list-style: none; margin: 0; padding: 0; }
.nav-links > li { position: relative; }
.nav-links a {
  display: block;
  padding: .55rem .78rem;
  border-radius: 8px;
  font-size: .95rem; font-weight: 500;
  color: var(--body); text-decoration: none;
  white-space: nowrap;
}
.nav-links a:hover { background: var(--sage-100); color: var(--forest-800); }
.nav-links a[aria-current="page"] { color: var(--forest-800); font-weight: 600; background: var(--sage-100); }

/* Dropdown */
.has-menu > button {
  display: flex; align-items: center; gap: .3rem;
  padding: .55rem .78rem; border: 0; border-radius: 8px;
  background: transparent; cursor: pointer;
  font-family: var(--f-body); font-size: .95rem; font-weight: 500; color: var(--body);
}
.has-menu > button:hover { background: var(--sage-100); color: var(--forest-800); }
.has-menu > button svg { transition: transform .2s; }
.has-menu[data-open="true"] > button svg { transform: rotate(180deg); }

.submenu {
  position: absolute; top: calc(100% + 8px); left: 0;
  min-width: 244px; padding: .5rem;
  background: var(--paper-0); border: 1px solid var(--line);
  border-radius: var(--r); box-shadow: var(--sh-md);
  list-style: none; margin: 0;
  opacity: 0; visibility: hidden; transform: translateY(-6px);
  transition: opacity .18s, transform .18s, visibility .18s;
}
.has-menu[data-open="true"] .submenu { opacity: 1; visibility: visible; transform: translateY(0); }
.submenu a { padding: .6rem .8rem; font-size: .94rem; border-radius: 8px; }
.submenu a small { display: block; font-size: .78rem; color: var(--muted); font-weight: 400; }

.nav-cta { display: flex; align-items: center; gap: .6rem; flex-shrink: 0; }
.nav-phone {
  display: inline-flex; align-items: center; gap: .4rem;
  font-weight: 600; font-size: .95rem; color: var(--forest-800); text-decoration: none;
  padding: .5rem .7rem; border-radius: 8px;
}
.nav-phone:hover { background: var(--sage-100); color: var(--forest-900); }
.nav-cta .btn { min-height: 46px; padding: .6rem 1.3rem; font-size: .95rem; }

.nav-toggle {
  display: none;
  width: 46px; height: 46px;
  align-items: center; justify-content: center;
  border: 1px solid var(--line); border-radius: 10px;
  background: var(--paper-0); cursor: pointer;
}
.nav-toggle span {
  position: relative; display: block; width: 20px; height: 2px;
  background: var(--forest-800); border-radius: 2px; transition: .2s;
}
.nav-toggle span::before, .nav-toggle span::after {
  content: ''; position: absolute; left: 0; width: 20px; height: 2px;
  background: var(--forest-800); border-radius: 2px; transition: .2s;
}
.nav-toggle span::before { top: -6px; }
.nav-toggle span::after { top: 6px; }
.nav-toggle[aria-expanded="true"] span { background: transparent; }
.nav-toggle[aria-expanded="true"] span::before { top: 0; transform: rotate(45deg); }
.nav-toggle[aria-expanded="true"] span::after { top: 0; transform: rotate(-45deg); }

@media (max-width: 1080px) {
  .nav-links, .nav-cta .nav-phone { display: none; }
  .nav-toggle { display: flex; }
}
@media (max-width: 620px) {
  .nav-cta .btn { display: none; }
  .brand-name b { font-size: 1.05rem; }
}

/* Mobile drawer */
.mobile-menu {
  position: fixed; inset: var(--nav-h) 0 0;
  background: var(--cream);
  z-index: 999;
  padding: 1.5rem 0 7rem;
  overflow-y: auto;
  transform: translateX(100%);
  transition: transform .28s cubic-bezier(.4,0,.2,1);
  visibility: hidden;
}
.mobile-menu.is-open { transform: translateX(0); visibility: visible; }

/* Scroll lock while the drawer is open. The header is pinned with
   position:fixed for the duration: overflow:hidden on <body> removes it from
   its sticky context, and it used to disappear off the top of the screen the
   moment the page had been scrolled, which also took the close button with
   it. */
body.scroll-locked { overflow: hidden; }
body.scroll-locked .site-header {
  position: fixed;
  top: 0; left: 0; right: 0;
}
.mobile-menu ul { list-style: none; margin: 0; padding: 0; }
.mobile-menu > .container > ul > li { border-bottom: 1px solid var(--line); }
/* :not(.btn) matters here. The drawer's two call-to-action buttons are <a>
   elements, so without it this rule overrode both their colour and their
   padding: "Book a Tour" rendered forest-800 on clay-600 at 1.93:1, and it
   is the primary conversion control on every page at mobile width. */
.mobile-menu a:not(.btn) {
  display: block; padding: 1rem .25rem;
  font-size: 1.08rem; font-weight: 500; color: var(--forest-800); text-decoration: none;
}
.mobile-menu a[aria-current="page"]:not(.btn) { color: var(--clay-600); font-weight: 600; }
.mobile-menu .m-group-label {
  padding: 1rem .25rem .35rem;
  font-size: .74rem; letter-spacing: .14em; text-transform: uppercase;
  color: var(--sage-ink); font-weight: 700;
}
.mobile-menu .m-sub a { padding: .65rem .25rem .65rem 1rem; font-size: 1rem; color: var(--body); }
.mobile-menu .m-actions { display: grid; gap: .75rem; margin-top: 1.75rem; }

/* Sticky mobile call bar */
.mobile-bar {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 1001;
  display: none; gap: .6rem; padding: .7rem .9rem calc(.7rem + env(safe-area-inset-bottom));
  background: rgba(255,255,255,.97);
  backdrop-filter: blur(10px);
  border-top: 1px solid var(--line);
  box-shadow: 0 -4px 24px rgba(31,59,44,.10);
}
.mobile-bar .btn { flex: 1; min-height: 50px; padding: .7rem 1rem; font-size: 1rem; }
@media (max-width: 780px) {
  .mobile-bar { display: flex; }
  body { padding-bottom: 76px; }
}

/* --------------------------------------------------------------------------
   6. HERO
   -------------------------------------------------------------------------- */
.hero {
  position: relative;
  padding-block: clamp(3rem, 7vw, 5.5rem) clamp(3.5rem, 8vw, 6rem);
  background:
    radial-gradient(60rem 34rem at 88% -10%, var(--sage-100), transparent 65%),
    radial-gradient(46rem 28rem at 2% 105%, var(--clay-100), transparent 60%),
    var(--cream);
  overflow: hidden;
}
.hero-grid {
  display: grid;
  grid-template-columns: 1.06fr .94fr;
  gap: clamp(2rem, 5vw, 4rem);
  align-items: center;
}
@media (max-width: 900px) { .hero-grid { grid-template-columns: 1fr; } }

/* --- Availability line ---------------------------------------------------
   This was a pill: rounded 100px chip, drop shadow, semibold sans, and a round
   dot with a glow ring. That combination is the most saturated tell on the
   web right now; it appears on essentially every SaaS and AI landing page, and
   on a care home it reads as software rather than as a house.

   Rebuilt in the vocabulary the rest of this site already uses for facts about
   the house: monospace, uppercase, letterspaced, square corners, a hairline
   doing the work a border and a shadow were doing before. It reads as a line
   from a record, which is what it is. The pulse stays, because a status
   indicator that moves is the one part of the original worth keeping, and the
   global prefers-reduced-motion rule neutralises it for anyone who asks. */
.availability {
  display: inline-flex;
  align-items: center;
  gap: .65rem;
  margin: 0 0 1.5rem;
  padding-bottom: .5rem;
  border-bottom: 1px solid var(--rule-soft);
  font-family: var(--f-mono);
  font-size: .78rem;
  font-weight: 500;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--sage-ink);          /* 6.50:1 at worst on the hero wash */
}
.availability-mark {
  width: 7px; height: 7px;
  flex: none;
  background: var(--good);          /* 4.32:1 at worst, a graphic needs 3:1 */
  animation: availability 2.6s ease-in-out infinite;
}
@keyframes availability { 0%, 100% { opacity: 1 } 50% { opacity: .28 } }

@media (max-width: 560px) {
  .availability { font-size: .72rem; letter-spacing: .1em; gap: .5rem; }
}

.hero h1 { margin-bottom: 1.1rem; }
.hero h1 .line { display: block; }
.hero p.lead { max-width: 32rem; margin-bottom: 1.9rem; }

.hero-media { position: relative; }
.hero-media img {
  width: 100%;
  aspect-ratio: 4 / 3;
  object-fit: cover;
  border-radius: var(--r-xl);
  box-shadow: var(--sh-lg);
}
.hero-media::after {
  content: '';
  position: absolute; inset: auto -14px -14px auto;
  width: 62%; height: 62%;
  border: 2px solid var(--sage-300);
  border-radius: var(--r-xl);
  z-index: -1;
}

.hero-float {
  position: absolute; left: -18px; bottom: 26px;
  display: flex; align-items: center; gap: .75rem;
  padding: .85rem 1.15rem;
  background: var(--paper-0); border-radius: var(--r);
  box-shadow: var(--sh-md);
  max-width: 250px;
}
.hero-float .big {
  font-family: var(--f-display); font-size: 1.65rem;
  color: var(--forest-700); font-weight: 700; line-height: 1;
}
.hero-float .cap { font-size: .82rem; color: var(--muted); line-height: 1.3; }
@media (max-width: 560px) { .hero-float { left: 8px; bottom: 8px; max-width: 210px; padding: .7rem .95rem; } }

/* Page header (interior pages) */
.page-header {
  padding-block: clamp(2.75rem, 6vw, 4.5rem);
  background:
    radial-gradient(46rem 26rem at 88% 0%, var(--sage-100), transparent 62%),
    var(--cream);
  border-bottom: 1px solid var(--line);
}
.page-header h1 { margin-bottom: .7rem; }
.page-header p { max-width: 46rem; font-size: 1.13rem; color: var(--muted); }

.crumbs { font-size: .87rem; color: var(--muted); margin-bottom: 1rem; }
.crumbs a { color: var(--muted); text-decoration: none; }
.crumbs a:hover { color: var(--forest-700); text-decoration: underline; }
.crumbs span { margin: 0 .45rem; opacity: .55; }

/* --------------------------------------------------------------------------
   7. TRUST BAR / STATS
   -------------------------------------------------------------------------- */
.trustbar {
  background: var(--paper-0);
  border-block: 1px solid var(--line);
  padding-block: 1.6rem;
}
.trustbar .row {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: 1.25rem 2rem;
}
.trust-item { display: flex; align-items: center; gap: .8rem; }
.trust-item .ico {
  flex-shrink: 0; width: 42px; height: 42px;
  display: grid; place-items: center;
  background: var(--sage-50); border-radius: 12px;
  color: var(--forest-600);
}
.trust-item b { display: block; font-size: .98rem; color: var(--forest-900); font-weight: 600; line-height: 1.25; }
.trust-item span { font-size: .84rem; color: var(--muted); }

.stat-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(170px, 1fr)); gap: 1.25rem; }
.stat {
  padding: 1.5rem 1.35rem;
  background: var(--paper-0);
  border: 1px solid var(--line);
  border-radius: var(--r);
  text-align: center;
}
.stat .n {
  display: block;
  font-family: var(--f-display); font-weight: 700;
  font-size: clamp(2rem, 4vw, 2.7rem);
  color: var(--forest-700); line-height: 1;
  margin-bottom: .4rem;
}
.stat .l { font-size: .92rem; color: var(--muted); }
.section--forest .stat { background: rgba(255,255,255,.09); border-color: rgba(255,255,255,.18); }
.section--forest .stat .n { color: var(--paper-0); }
.section--forest .stat .l { color: #CFDDCE; }

/* --------------------------------------------------------------------------
   8. CARDS
   -------------------------------------------------------------------------- */
.card {
  padding: 1.9rem 1.7rem;
  background: var(--paper-0);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  box-shadow: var(--sh-sm);
  transition: transform .22s ease, box-shadow .22s ease, border-color .22s ease;
}
.card:hover { transform: translateY(-4px); box-shadow: var(--sh-md); border-color: var(--sage-200); }
.card h3 { margin-bottom: .55rem; font-size: 1.28rem; }
.card p { font-size: .99rem; color: var(--body); margin-bottom: 0; }

.card-ico {
  width: 54px; height: 54px;
  display: grid; place-items: center;
  background: linear-gradient(150deg, var(--sage-100), var(--sage-50));
  border-radius: 15px;
  color: var(--forest-600);
  margin-bottom: 1.1rem;
}
.card-ico svg { width: 27px; height: 27px; }

.card--link { display: block; text-decoration: none; color: inherit; }
.card--link .more {
  display: inline-flex; align-items: center; gap: .35rem;
  margin-top: 1rem; font-size: .93rem; font-weight: 600; color: var(--clay-600);
}
.card--link:hover .more { gap: .6rem; }
.card--flat { box-shadow: none; }
.card--flat:hover { transform: none; box-shadow: var(--sh-sm); }

/* Feature list with checks */
.checks { list-style: none; margin: 0; padding: 0; display: grid; gap: .7rem; }
.checks li { position: relative; padding-left: 2rem; font-size: 1rem; }
.checks li::before {
  content: '';
  position: absolute; left: 0; top: .38em;
  width: 20px; height: 20px;
  background: var(--sage-100);
  border-radius: 50%;
}
.checks li::after {
  content: '';
  position: absolute; left: 6px; top: .62em;
  width: 8px; height: 4.5px;
  border-left: 2px solid var(--forest-600);
  border-bottom: 2px solid var(--forest-600);
  transform: rotate(-45deg);
}
.checks--tight li { font-size: .95rem; }
.section--forest .checks li::before { background: rgba(255,255,255,.18); }
.section--forest .checks li::after { border-color: var(--paper-0); }

.crosses { list-style: none; margin: 0; padding: 0; display: grid; gap: .7rem; }
.crosses li { position: relative; padding-left: 2rem; font-size: 1rem; }
.crosses li::before {
  content: '×';
  position: absolute; left: 0; top: 0;
  width: 20px; height: 20px; margin-top: .3em;
  display: grid; place-items: center;
  background: var(--clay-100); color: var(--clay-ink);   /* 4.32 -> 5.96:1 */
  border-radius: 50%; font-size: .95rem; font-weight: 700; line-height: 1;
}

/* --------------------------------------------------------------------------
   9. COMPARISON TABLE  (the differentiator)
   -------------------------------------------------------------------------- */
.compare-wrap {
  overflow-x: auto;
  border-radius: var(--r-lg);
  border: 1px solid var(--line);
  background: var(--paper-0);
  box-shadow: var(--sh-md);
  -webkit-overflow-scrolling: touch;
}
table.compare {
  width: 100%;
  min-width: 660px;
  border-collapse: collapse;
  font-size: 1rem;
}
table.compare th, table.compare td {
  padding: 1rem 1.15rem;
  text-align: left;
  border-bottom: 1px solid var(--line);
  vertical-align: middle;
}
table.compare thead th {
  background: var(--cream);
  font-family: var(--f-body);
  font-size: .82rem; font-weight: 700;
  letter-spacing: .08em; text-transform: uppercase;
  color: var(--muted);
  border-bottom: 2px solid var(--line);
}
table.compare thead th.us {
  background: var(--forest-700);
  color: var(--paper-0);
  position: relative;
}
table.compare tbody td.us {
  background: var(--sage-50);
  font-weight: 600;
  color: var(--forest-800);
}
table.compare tbody tr:last-child td { border-bottom: 0; }
table.compare tr.total td {
  background: var(--cream-200);
  font-weight: 700;
  font-size: 1.12rem;
  color: var(--forest-900);
}
table.compare tr.total td.us { background: var(--forest-700); color: var(--paper-0); }
table.compare td.num { font-variant-numeric: tabular-nums; white-space: nowrap; }
table.compare .sub { display: block; font-size: .83rem; font-weight: 400; color: var(--muted); }
table.compare td.us .sub { color: var(--forest-700); }   /* 5.57 -> 7.73:1 */
table.compare tr.total td.us .sub { color: var(--sage-200); }

/* Answers in a comparison table.
   These replace a pair of red and green pills. Two reasons they went, and the
   second is the one that mattered.

   The look: a fully-rounded tinted badge with small bold text is the status
   chip shipped by every dashboard on the internet. It was the one component
   on this site that announced itself as a component.

   The meaning: red and green are read as bad and good, but these cells answer
   "yes or no", not "good or bad". So the old markup put a red badge on our own
   row for not keeping a nurse on site around the clock, and a green one on the
   nursing home for keeping one, on a page we wrote. The colour was arguing
   against the page. It also had no way to say "sometimes", so a heavily
   qualified Medicare answer was painted the same green as a plain yes.

   What replaces it is the convention printed comparison tables have used for
   a century: a filled ring for yes, half filled for a qualified yes, hollow
   for no. The state is carried by SHAPE, so it survives colour blindness and
   a phone at minimum brightness at eleven at night, which is when this page is
   actually read. Drawn in currentColor, so it inverts by itself inside the
   dark highlighted row and needs no separate rule for it. */
/* Grid rather than an inline mark, so that the five answers long enough to
   wrap ("Yes, required of every Type B home") keep their second and third
   lines aligned to the first word instead of running back underneath the
   ring. The ring is hung in its own column and optically centred on the first
   line; em units keep it correct across the four different font sizes this
   table uses between the normal rows and the highlighted one. */
.ans {
  display: grid;
  grid-template-columns: max-content 1fr;
  column-gap: .5em;
}
.ans::before {
  content: "";
  width: .62em;
  height: .62em;
  margin-top: .42em;
  border: 1.5px solid currentColor;
  border-radius: 50%;
}
.ans--yes::before { background: currentColor; }
/* A qualified yes. "Sometimes" is not a smaller yes, it is a different answer.
   Hard stops, so no engine interpolates a grey seam down the middle. */
.ans--part::before {
  background: linear-gradient(to right, currentColor 0 50%, transparent 50% 100%);
}

/* Row-highlight variant.
   The default .compare highlights a COLUMN (the Daraan column runs down the
   right). Some comparisons instead put each option on its own row, so the
   emphasis has to run horizontally. Without this the dark fill starts at the
   second cell and the row header is left pale, which reads as a rendering
   fault rather than emphasis. */
table.compare--byrow tr.total th[scope="row"] {
  background: var(--forest-700);
  color: var(--paper-0);
}
table.compare--byrow tr.total th[scope="row"] .sub { color: var(--sage-200); }

.table-note { font-size: .87rem; color: var(--muted); margin-top: 1rem; }
.scroll-hint { display: none; font-size: .84rem; color: var(--muted); margin-bottom: .6rem; }
@media (max-width: 720px) { .scroll-hint { display: block; } }

/* --------------------------------------------------------------------------
   10. PRICING CARDS
   -------------------------------------------------------------------------- */
.price-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(290px, 1fr)); gap: 1.5rem; align-items: start; }

.price-card {
  position: relative;
  padding: 2rem 1.75rem;
  background: var(--paper-0);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  box-shadow: var(--sh-sm);
  display: flex; flex-direction: column;
  height: 100%;
}
.price-card.featured {
  border: 2px solid var(--forest-600);
  box-shadow: var(--sh-lg);
}
.price-card .tag {
  position: absolute; top: -13px; left: 50%; transform: translateX(-50%);
  padding: .3rem 1rem;
  background: var(--forest-700); color: var(--paper-0);
  border-radius: 100px; font-size: .76rem; font-weight: 700;
  letter-spacing: .07em; text-transform: uppercase;
  white-space: nowrap;
}
.price-card .lvl { font-size: .8rem; font-weight: 700; letter-spacing: .12em; text-transform: uppercase; color: var(--clay-600); margin-bottom: .35rem; }
.price-card h3 { margin-bottom: .5rem; }
.price-card .who { font-size: .96rem; color: var(--muted); min-height: 3.2em; margin-bottom: 1.25rem; }
.price-card .amount {
  display: flex; align-items: baseline; gap: .35rem;
  padding-bottom: 1.25rem; margin-bottom: 1.25rem;
  border-bottom: 1px solid var(--line);
}
.price-card .amount b {
  font-family: var(--f-display); font-size: 2.55rem; font-weight: 700;
  color: var(--forest-800); line-height: 1;
}
.price-card .amount span { font-size: .98rem; color: var(--muted); }
.price-card .incl { font-size: .8rem; font-weight: 700; letter-spacing: .1em; text-transform: uppercase; color: var(--sage-ink); margin-bottom: .8rem; }
.price-card .checks { margin-bottom: 1.5rem; }
.price-card .btn { margin-top: auto; }

.fees {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 1rem;
}
.fee {
  display: flex; justify-content: space-between; align-items: center; gap: 1rem;
  padding: 1.1rem 1.3rem;
  background: var(--paper-0); border: 1px solid var(--line); border-radius: var(--r);
}
.fee .k { font-size: .97rem; color: var(--body); }
.fee .v { font-family: var(--f-display); font-size: 1.28rem; font-weight: 700; color: var(--forest-700); white-space: nowrap; }

/* --------------------------------------------------------------------------
   11. GALLERY
   -------------------------------------------------------------------------- */
/* Masonry, not a grid of equal slots. A uniform 4:3 crop on every photo is
   what makes a gallery read as "assets filling containers" rather than
   "photographs someone took". CSS columns give true masonry with no gaps;
   each photo keeps its own shape via --ar. DOM order is preserved for
   screen readers and keyboard tabbing. */
.gallery { columns: 3 280px; column-gap: 1.15rem; }
.gal-item {
  position: relative;
  margin: 0 0 1.15rem;
  break-inside: avoid;
  -webkit-column-break-inside: avoid;
  border-radius: var(--r-lg); overflow: hidden;
  cursor: zoom-in;
  background: var(--cream-200);
  border: 0; padding: 0;
  display: block; width: 100%;
  text-align: left;
}
.gal-item img { width: 100%; aspect-ratio: var(--ar, 4/3); object-fit: cover; transition: transform .5s cubic-bezier(.2,.8,.2,1); }
.gal-item.tall img { aspect-ratio: 3/4; }
.gal-item:hover img { transform: scale(1.05); }
.gal-item figcaption {
  position: absolute; left: 0; right: 0; bottom: 0;
  padding: 1.6rem 1.1rem .95rem;
  background: linear-gradient(to top, rgba(31,59,44,.86), transparent);
  color: var(--paper-0); font-size: .98rem; font-weight: 600;
}

.lightbox {
  position: fixed; inset: 0; z-index: 2000;
  display: none;
  align-items: center; justify-content: center;
  padding: 1.5rem;
  background: rgba(20,33,26,.94);
  backdrop-filter: blur(4px);
}
.lightbox.is-open { display: flex; }
.lightbox img { max-width: 100%; max-height: 84vh; border-radius: var(--r); box-shadow: var(--sh-lg); }
.lightbox .lb-cap { position: absolute; bottom: 1.75rem; left: 0; right: 0; text-align: center; color: #E9F0E9; font-size: 1rem; }
.lightbox button {
  position: absolute; top: 1.1rem; right: 1.1rem;
  width: 48px; height: 48px; border-radius: 50%;
  border: 1px solid rgba(255,255,255,.3);
  background: rgba(255,255,255,.12); color: var(--paper-0);
  font-size: 1.5rem; line-height: 1; cursor: pointer;
}
.lightbox button:hover { background: rgba(255,255,255,.24); }

/* --------------------------------------------------------------------------
   12. FAQ ACCORDION
   -------------------------------------------------------------------------- */
.faq { display: grid; gap: .85rem; }
.faq-item {
  background: var(--paper-0);
  border: 1px solid var(--line);
  border-radius: var(--r);
  overflow: hidden;
}
.faq-item[data-open="true"] { border-color: var(--sage-300); box-shadow: var(--sh-sm); }
.faq-q {
  width: 100%;
  display: flex; align-items: center; justify-content: space-between; gap: 1.25rem;
  padding: 1.2rem 1.4rem;
  border: 0; background: transparent; cursor: pointer;
  font-family: var(--f-display); font-size: 1.12rem; font-weight: 600;
  color: var(--forest-900); text-align: left; line-height: 1.35;
}
.faq-q:hover { background: var(--sage-50); }
.faq-q .chev {
  flex-shrink: 0; width: 26px; height: 26px;
  display: grid; place-items: center;
  border-radius: 50%; background: var(--sage-100); color: var(--forest-700);
  font-size: 1rem; font-weight: 700; transition: transform .25s;
}
.faq-item[data-open="true"] .chev { transform: rotate(45deg); }
.faq-a { display: none; padding: 0 1.4rem 1.35rem; }
.faq-item[data-open="true"] .faq-a { display: block; }
.faq-a p { font-size: 1rem; color: var(--body); }
.faq-a p:last-child { margin-bottom: 0; }

/* --------------------------------------------------------------------------
   13. TESTIMONIALS
   -------------------------------------------------------------------------- */
.quote {
  padding: 2rem 1.85rem;
  background: var(--paper-0);
  border: 1px solid var(--line);
  border-radius: var(--r);
}
.quote blockquote { margin: 0 0 1.15rem; font-size: 1.06rem; line-height: 1.65; color: var(--body); }
.quote blockquote::before { content: '“'; font-family: var(--f-display); font-size: 2.6rem; color: var(--sage-300); line-height: 0; vertical-align: -.35em; margin-right: .1em; }
.quote .who { display: flex; align-items: center; gap: .75rem; }
.quote .who .av {
  width: 42px; height: 42px; border-radius: 50%;
  background: var(--sage-100); color: var(--forest-700);
  display: grid; place-items: center;
  font-family: var(--f-display); font-weight: 700; font-size: 1.05rem;
}
.quote .who b { display: block; font-size: .98rem; color: var(--forest-900); }
.quote .who span { font-size: .86rem; color: var(--muted); }

.placeholder-note {
  padding: 1.15rem 1.35rem;
  background: var(--clay-100);
  border: 1px dashed var(--clay-500);
  border-radius: var(--r);
  font-size: .93rem; color: var(--clay-600);
}
.placeholder-note b { color: var(--clay-600); }

/* --------------------------------------------------------------------------
   14. FORMS
   -------------------------------------------------------------------------- */
.form-card {
  padding: clamp(1.75rem, 3.5vw, 2.75rem);
  background: var(--paper-0);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  box-shadow: var(--sh-md);
}
.field { margin-bottom: 1.15rem; }
.field label {
  display: block; margin-bottom: .45rem;
  font-size: .93rem; font-weight: 600; color: var(--forest-900);
}
.field .req { color: var(--clay-600); }
.field input, .field select, .field textarea {
  width: 100%;
  min-height: 52px;
  padding: .8rem 1rem;
  font-family: var(--f-body); font-size: 1rem; color: var(--ink);
  background: var(--cream);
  border: 1.5px solid var(--line);
  border-radius: var(--r-sm);
  transition: border-color .18s, box-shadow .18s, background .18s;
}
.field textarea { min-height: 110px; resize: vertical; line-height: 1.6; }
.field input:focus, .field select:focus, .field textarea:focus {
  outline: none;
  background: var(--paper-0);
  border-color: var(--forest-600);
  box-shadow: 0 0 0 4px var(--sage-100);
}
.field input::placeholder, .field textarea::placeholder { color: #9BA39D; }
.field .hint { margin-top: .35rem; font-size: .84rem; color: var(--muted); }
.field-row { display: grid; grid-template-columns: 1fr 1fr; gap: 1.15rem; }
@media (max-width: 540px) { .field-row { grid-template-columns: 1fr; gap: 0; } }

/* ==========================================================================
   CUSTOM SELECT AND DATE PICKER

   A native <select>'s dropdown panel and a native <input type="date">'s
   calendar are both drawn by the operating system. CSS cannot reach either, so
   matching them to this site meant building the panels.

   The native controls stay in the DOM and remain the form value and the
   no-JS fallback; JS hides them and mirrors. If main.js fails to load, the form
   still works with the browser's own widgets, which is the correct failure
   mode for the page that books the tours.
   ========================================================================== */

/* Native control, still submitting, no longer painted. Not display:none, which
   would take it out of the form in some older browsers. */
.field .is-enhanced {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%);
  white-space: nowrap; border: 0;
}

/* The trigger reuses the input styling exactly, so an enhanced control and a
   plain text input are indistinguishable until opened. */
.ui-trigger {
  width: 100%;
  min-height: 52px;
  display: flex; align-items: center; justify-content: space-between; gap: 1rem;
  padding: .8rem 1rem;
  font-family: var(--f-body); font-size: 1rem; text-align: left;
  color: var(--ink);
  background: var(--cream);
  border: 1.5px solid var(--line);
  border-radius: var(--r-input);
  cursor: pointer;
  transition: border-color .18s, box-shadow .18s, background .18s;
}
.ui-trigger:hover { border-color: var(--rule); }
.ui-trigger:focus-visible,
.ui-trigger[aria-expanded="true"] {
  outline: none;
  background: var(--paper-0);
  border-color: var(--forest-600);
  box-shadow: 0 0 0 4px var(--sage-100);
}
.ui-trigger .ui-value {
  flex: 1; min-width: 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.ui-trigger.is-placeholder .ui-value { color: #6B6257; }   /* 5.2:1 on --cream */
.ui-trigger .ui-caret {
  flex: none; width: 11px; height: 7px; color: var(--forest-700);
  transition: transform .18s var(--ease);
}
.ui-trigger[aria-expanded="true"] .ui-caret { transform: rotate(180deg); }

/* --- The panel ---------------------------------------------------------- */
/* The panel is positioned against a wrapper holding only the trigger, not
   against .field. Anchoring to .field would measure from the top of the label,
   so an upward-opening panel would float above the label and leave a gap over
   the control it belongs to. */
.ui-anchor { position: relative; display: block; }
.ui-panel {
  position: absolute; z-index: 60;
  top: calc(100% + .4rem); left: 0; right: 0;
  background: var(--paper-0);
  border: 1px solid var(--rule-soft);
  border-radius: var(--r-input);
  box-shadow: var(--sh-md);
  padding: .35rem;
  max-height: 17rem;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
}
.ui-panel[hidden] { display: none; }
/* Opens upward when there is not room below. */
.ui-panel.is-above { top: auto; bottom: calc(100% + .4rem); }

.ui-option {
  display: block; width: 100%;
  padding: .7rem .85rem;
  min-height: 44px;
  font-family: var(--f-body); font-size: 1rem; text-align: left;
  color: var(--ink-body);
  background: transparent; border: 0; border-radius: 3px;
  cursor: pointer;
}
.ui-option:hover, .ui-option.is-active { background: var(--sage-50); color: var(--ink); }
.ui-option[aria-selected="true"] {
  background: var(--sage-100); color: var(--forest-800); font-weight: 600;
}

/* --- Calendar ------------------------------------------------------------ */
/* .ui-panel caps its height and scrolls, which is right for a list of
   options and wrong for a month grid: it would clip the last week. */
.ui-cal { width: min(20rem, 78vw); padding: .85rem; max-height: none; overflow: visible; }
.ui-cal-head {
  display: flex; align-items: center; justify-content: space-between;
  gap: .5rem; margin-bottom: .65rem;
}
.ui-cal-title {
  font-family: var(--f-body); font-weight: 600; font-size: 1rem; color: var(--ink);
}
.ui-cal-nav {
  width: 40px; height: 40px; flex: none;
  display: grid; place-items: center;
  background: transparent; border: 1px solid var(--rule-soft);
  border-radius: var(--r-input); color: var(--forest-700); cursor: pointer;
}
.ui-cal-nav:hover:not(:disabled) { background: var(--sage-50); border-color: var(--sage-300); }
.ui-cal-nav:disabled { opacity: .35; cursor: default; }

.ui-cal-grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 2px; }
.ui-cal-dow {
  font-family: var(--f-mono); font-size: .68rem; letter-spacing: .06em;
  text-transform: uppercase; color: var(--ink-soft);
  text-align: center; padding: .35rem 0 .5rem;
}
.ui-day {
  aspect-ratio: 1; min-height: 40px;
  display: grid; place-items: center;
  font-family: var(--f-body); font-size: .95rem; color: var(--ink-body);
  background: transparent; border: 1px solid transparent;
  border-radius: 3px; cursor: pointer;
}
.ui-day:hover:not(:disabled) { background: var(--sage-50); }
.ui-day.is-active { border-color: var(--forest-600); }
.ui-day.is-today { font-weight: 700; color: var(--clay-ink); }
.ui-day[aria-selected="true"] {
  background: var(--forest-700); color: var(--paper-0); font-weight: 600;
}
.ui-day:disabled { color: var(--rule-soft); cursor: default; }
.ui-day.is-blank { visibility: hidden; }


.form-note { margin-top: 1rem; font-size: .87rem; color: var(--muted); text-align: center; }

/* Inline submit error. This used to be a window.alert(), which on a care-home
   site reads like a scam popup and, on iOS, blocks the page until dismissed.
   role="alert" so screen readers announce it without moving focus. */
.form-error {
  margin-top: 1rem;
  padding: .95rem 1.15rem;
  background: var(--clay-100);
  border: 1px solid var(--clay-500);
  border-radius: var(--r-input);
  color: var(--clay-ink);      /* 5.96:1 on clay-100 */
  font-size: .95rem;
}
.form-error[hidden] { display: none; }
.form-error a { color: var(--clay-ink); font-weight: 600; }

.form-success {
  display: none;
  padding: 2.25rem 1.75rem;
  text-align: center;
  background: var(--sage-50);
  border: 2px solid var(--sage-300);
  border-radius: var(--r-lg);
}
.form-success.is-visible { display: block; }
.form-success .tick {
  width: 64px; height: 64px; margin: 0 auto 1.1rem;
  display: grid; place-items: center;
  background: var(--forest-600); color: var(--paper-0);
  border-radius: 50%; font-size: 1.9rem;
}
.form-success h3 { margin-bottom: .6rem; }
.form-success dl { display: grid; gap: .5rem; margin: 1.35rem 0; text-align: left; }
.form-success dl div { display: flex; justify-content: space-between; gap: 1rem; padding: .6rem .9rem; background: var(--paper-0); border-radius: var(--r-sm); }
.form-success dt { font-size: .92rem; color: var(--muted); }
.form-success dd { margin: 0; font-weight: 600; color: var(--forest-900); font-size: .95rem; text-align: right; }

/* --------------------------------------------------------------------------
   15. CTA BAND
   -------------------------------------------------------------------------- */
.cta-band {
  position: relative;
  padding-block: clamp(3.25rem, 7vw, 5rem);
  background: linear-gradient(155deg, var(--forest-800), var(--forest-700) 62%, var(--forest-800));
  color: #E9F0E9;
  text-align: center;
  overflow: hidden;
}
.cta-band::before {
  content: '';
  position: absolute; inset: 0;
  background: radial-gradient(34rem 20rem at 82% 12%, rgba(198,219,185,.16), transparent 65%);
}
.cta-band > .container { position: relative; }
.cta-band h2 { color: var(--paper-0); margin-bottom: .85rem; }
.cta-band p { max-width: 40rem; margin-inline: auto; color: #D3E0D2; font-size: 1.1rem; margin-bottom: 2rem; }
.cta-band .btn-row { justify-content: center; }
.cta-sub { margin-top: 1.5rem; font-size: .92rem; color: #B9CCB8; }

/* Contact strip */
.contact-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); gap: 1.25rem; }
.contact-item {
  padding: 1.6rem 1.4rem;
  background: var(--paper-0); border: 1px solid var(--line); border-radius: var(--r-lg);
  text-align: center;
}
.contact-item .ico {
  width: 50px; height: 50px; margin: 0 auto .9rem;
  display: grid; place-items: center;
  background: var(--sage-50); border-radius: 14px; color: var(--forest-600);
}
.contact-item h2, .contact-item h3 { font-size: 1.1rem; margin-bottom: .4rem; }
.contact-item a { font-weight: 600; text-decoration: none; font-size: 1.03rem; }
.contact-item p { font-size: .9rem; color: var(--muted); margin: .3rem 0 0; }

/* --------------------------------------------------------------------------
   16. FOOTER
   -------------------------------------------------------------------------- */
.site-footer {
  background: var(--forest-900);
  color: #B9C7BC;
  padding-block: clamp(3rem, 6vw, 4.5rem) 2rem;
}
/* Two explicit rows rather than one auto-fit grid. With everything in a single
   grid the brand and contact blocks needed to span two columns each, which left
   the five link groups wrapping onto a second row with three empty cells at
   1440px. Splitting it means neither row can go ragged. */
.footer-top {
  display: grid;
  grid-template-columns: 1.35fr 1fr;
  gap: 2.5rem;
  padding-bottom: 2.25rem;
}
.footer-links {
  display: grid;
  grid-template-columns: repeat(5, minmax(0, 1fr));
  gap: 2rem 1.75rem;
  padding-bottom: 2.5rem;
  border-bottom: 1px solid rgba(255,255,255,.12);
}
@media (max-width: 1080px) {
  .footer-links { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}
@media (max-width: 760px) {
  .footer-top  { grid-template-columns: 1fr; gap: 2rem; }
  .footer-links { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 380px) {
  .footer-links { grid-template-columns: 1fr; }
}

/* Actions sit under the contact details, visually separated from them. */
.footer-actions {
  margin-top: 1rem; padding-top: 1rem;
  border-top: 1px solid rgba(255,255,255,.14);
}

.footer-brand { display: flex; align-items: center; gap: .7rem; margin-bottom: 1.1rem; text-decoration: none; }
.footer-brand img { width: 46px; height: 46px; border-radius: 50%; }
.footer-brand b { font-family: var(--f-display); font-size: 1.28rem; color: var(--paper-0); }
.site-footer p { font-size: .95rem; line-height: 1.7; }
/* These are h2 in the markup: as the top-level headings inside the footer
   landmark, h4 skipped a level after page content ended at h2. Both
   selectors kept so the visual treatment is unchanged. */
.site-footer h2, .site-footer h4 {
  color: var(--paper-0); font-family: var(--f-body);
  font-size: .8rem; font-weight: 700; letter-spacing: .13em; text-transform: uppercase;
  margin-bottom: 1.1rem;
}
.site-footer ul { list-style: none; margin: 0; padding: 0; display: grid; gap: .6rem; }
.site-footer ul a { color: #B9C7BC; text-decoration: none; font-size: .95rem; }
.site-footer ul a:hover { color: var(--paper-0); text-decoration: underline; }
.footer-contact a { display: block; color: var(--paper-0); font-weight: 600; text-decoration: none; margin-bottom: .3rem; }
.footer-contact a:hover { color: var(--sage-200); }
.footer-contact address { font-style: normal; font-size: .95rem; line-height: 1.7; margin-bottom: 1rem; }
.footer-bottom {
  padding-top: 1.75rem;
  display: flex; flex-wrap: wrap; gap: .75rem 1.5rem;
  justify-content: space-between; align-items: center;
  font-size: .87rem; color: #93A497;
}
.footer-bottom a { color: #93A497; }

/* --------------------------------------------------------------------------
   17. MISC
   -------------------------------------------------------------------------- */
.media-frame { border-radius: var(--r-xl); overflow: hidden; box-shadow: var(--sh-lg); }
.media-frame img { width: 100%; aspect-ratio: 4/3; object-fit: cover; }
.media-frame.portrait img { aspect-ratio: 3/4; }

/* A thick coloured left stripe is the callout cliché, and it was the last one
   left on the rebuilt pages. A hairline all the way round reads as a note
   someone set apart, not as an alert widget. */
.note-box {
  padding: 1.4rem 1.6rem;
  background: var(--sage-50);
  border: 1px solid var(--sage-300);
  border-radius: var(--r-plate);
}
.note-box p { font-size: .98rem; margin-bottom: 0; }

.tag-row { display: flex; flex-wrap: wrap; gap: .55rem; }
.tag-chip {
  padding: .42rem .95rem;
  background: var(--paper-0); border: 1px solid var(--sage-200);
  border-radius: 100px; font-size: .89rem; font-weight: 500; color: var(--forest-700);
}
.section--forest .tag-chip { background: rgba(255,255,255,.1); border-color: rgba(255,255,255,.22); color: #E9F0E9; }

.timeline { display: grid; gap: 0; }
.tl-item {
  position: relative;
  padding: 0 0 2rem 3.25rem;
  border-left: 2px solid var(--sage-200);
  margin-left: 1rem;
}
.tl-item:last-child { border-left-color: transparent; padding-bottom: 0; }
.tl-item .tl-dot {
  position: absolute; left: -1.1rem; top: 0;
  width: 2.2rem; height: 2.2rem;
  display: grid; place-items: center;
  background: var(--forest-600); color: var(--paper-0);
  border-radius: 50%; font-size: .82rem; font-weight: 700;
  border: 4px solid var(--cream);
}
/* The dot's ring has to match whatever ground the timeline sits on, or it
   reads as a mis-rendered halo. */
.section--white .tl-item .tl-dot { border-color: var(--paper-0); }
.section--p0 .tl-item .tl-dot { border-color: var(--paper-0); }
.section--p1 .tl-item .tl-dot { border-color: var(--paper-1); }
.section--p2 .tl-item .tl-dot { border-color: var(--paper-2); }
.section--p3 .tl-item .tl-dot { border-color: var(--paper-3); }
/* clay-600 measured 4.40:1 on --paper-2 and fails AA at this size. */
.tl-item .tl-time {
  font-family: var(--f-mono);
  font-size: .78rem; font-weight: 500; letter-spacing: .1em;
  text-transform: uppercase; color: var(--clay-ink); margin-bottom: .35rem;
}

/* Plain-marker variant. When each step already carries its own label
   (Morning, Midday, Evening) the numbers 1..6 are pure scaffolding, so the
   dot becomes a quiet node instead of a counter. */
.timeline--plain .tl-item { padding-left: 2.5rem; }
.timeline--plain .tl-item .tl-dot {
  width: .85rem; height: .85rem;
  left: -.5rem; top: .45rem;
  border-width: 3px;
  font-size: 0;
}
.tl-item h3 { font-size: 1.18rem; margin-bottom: .4rem; }
.tl-item p { font-size: .98rem; margin-bottom: 0; }

/* ==========================================================================
   MOTION

   Deliberately narrow. A fade-and-rise on every section as you scroll is the
   single most recognisable tell of a generated page, and it is exactly wrong
   for this one: people arrive here at eleven at night having had a bad week,
   and content that withholds itself until it has finished its entrance is an
   obstacle, not a flourish. Restraint is the voice.

   So motion is spent in three places only:

     1. ONE signature gesture. The clay rule above every heading draws itself
        in, left to right. It is the site's own mark, it is purely decorative,
        and because it is a ::before it can never hide a word of content.

     2. Things the visitor just did. A panel opening, an answer expanding, a
        photograph enlarging, a tour request being accepted. These are state
        changes, and a state change that happens instantly reads as a glitch.

     3. Two real sibling grids. The photographs of the house and the pricing
        tiers arrive in sequence, because they genuinely are a sequence.
        Nothing else on the site gets a scroll reveal.

   Easing is ease-out everywhere: entrances decelerate. No bounce, no elastic.
   Exits run at roughly three-quarters of their entrance, which is what makes
   a close feel responsive rather than reluctant.
   ========================================================================== */

:root {
  --ease-out-quint: cubic-bezier(0.22, 1, 0.36, 1);   /* entrances */
  --ease-out-expo:  cubic-bezier(0.16, 1, 0.3, 1);    /* the signature rule */
}

/* --- 1. The signature ----------------------------------------------------
   Gated on html.js-motion, which the inline script in partials/header.php
   sets before the first paint and removes again if main.js never arrives. */
html.js-motion .rule-head::before {
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform .5s var(--ease-out-expo);
}
html.js-motion .rule-head.is-in::before { transform: scaleX(1); }
html.js-motion .rule-head--center::before {
  transform: translateX(-50%) scaleX(0);
  transform-origin: center;
}
html.js-motion .rule-head--center.is-in::before { transform: translateX(-50%) scaleX(1); }

/* --- 2. Responses to something the visitor did ---------------------------
   Not gated: these should happen whether or not the scroll machinery is
   running. The reduced-motion block below still flattens them. */

/* The enhanced select and calendar panels. 140ms is inside the threshold at
   which a change still reads as instant, while still showing where the panel
   came from. */
.ui-panel:not([hidden]) { animation: ui-panel-in .14s var(--ease-out-quint) both; }
.ui-panel.is-above:not([hidden]) { animation-name: ui-panel-in-up; }
@keyframes ui-panel-in    { from { opacity: 0; transform: translateY(-6px); } }
@keyframes ui-panel-in-up { from { opacity: 0; transform: translateY(6px); } }

/* The photo viewer: the backdrop fades, the photograph eases up into it.
   Starting the photograph at .985 rather than 0 keeps it a movement rather
   than an inflation. */
.lightbox.is-open { animation: lb-fade .22s ease-out both; }
.lightbox.is-open img { animation: lb-rise .34s var(--ease-out-quint) both; }
@keyframes lb-fade { from { opacity: 0; } }
@keyframes lb-rise { from { opacity: 0; transform: translateY(10px) scale(.985); } }

/* The FAQ. 0fr to 1fr is the only way to transition to a height nobody has
   measured. .is-anim is added by main.js at the same moment it wraps the
   answer, so if that script never runs the original display:none rule still
   applies and no answer is left half-open. */
.faq-a.is-anim,
.faq-item[data-open="true"] .faq-a.is-anim {
  display: grid;
  grid-template-rows: 0fr;
  padding: 0;
  transition: grid-template-rows .2s var(--ease-out-quint);   /* closing */
}
.faq-item[data-open="true"] .faq-a.is-anim {
  grid-template-rows: 1fr;
  transition-duration: .28s;                                  /* opening */
}
/* Two details, both of which cost an hour if you miss them.

   min-height:0, because a grid item defaults to min-height:auto and refuses to
   shrink below its content, leaving the answer fully open at 0fr.

   No bottom padding, because with border-box sizing the padding is a floor the
   box cannot shrink past: the collapsed answer sat at exactly 1.35rem, the
   padding value, rather than at nothing. The gap under the last paragraph is a
   spacer inside the clipped box instead, so it collapses with everything else.
   Side padding is safe: it has no bearing on height. */
.faq-a.is-anim > .faq-a-in {
  min-height: 0;
  overflow: hidden;
  padding: 0 1.4rem;
}
.faq-a.is-anim > .faq-a-in::after { content: ""; display: block; height: 1.35rem; }

/* The two outcomes of the tour form. This is the moment the whole site exists
   for, so the confirmation is allowed a real entrance; the error is quieter,
   because nobody wants a failure announced with a flourish. */
.form-success.is-visible { animation: form-in .42s var(--ease-out-quint) both; }
.form-success.is-visible .tick { animation: tick-in .34s var(--ease-out-quint) .12s both; }
@keyframes form-in { from { opacity: 0; transform: translateY(14px); } }
@keyframes tick-in { from { opacity: 0; transform: scale(.9); } }

.form-error:not([hidden]) { animation: err-in .2s var(--ease-out-quint) both; }
@keyframes err-in { from { opacity: 0; transform: translateY(-5px); } }

/* --- 3. The one real sibling grid -----------------------------------------
   The photographs of the house, and nothing else. They sit three across, so
   the siblings are on screen together and the sequence is actually legible.
   The pricing tiers were tried here and cut: they are full-width stacked rows,
   only one is ever in view, and a fade on a block that size is a section
   reveal wearing a stagger's clothes.

   --anim-i is the item's position, set by main.js, capped so a long gallery
   never leaves the last photograph waiting. */
html.js-motion .gal-item {
  opacity: 0;
  transform: translateY(10px);
  transition: opacity .5s var(--ease-out-quint) calc(var(--anim-i, 0) * 55ms),
              transform .5s var(--ease-out-quint) calc(var(--anim-i, 0) * 55ms);
}
html.js-motion .gal-item.is-in { opacity: 1; transform: none; }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
  }
  .reveal { opacity: 1; transform: none; }
}

@media print {
  .site-header, .mobile-bar, .cta-band, .mobile-menu, .btn { display: none !important; }
  body { background: var(--paper-0); color: #000; padding: 0; }
}

/* ==========================================================================
   17b. EDITORIAL COMPONENTS
   Added for the home page rebuild. These exist alongside the older card/grid
   components rather than replacing them, so the pages not yet migrated keep
   working. As each page is rebuilt it moves onto these.

   The brief they answer: the old page repeated one rhythm eight times over
   (uppercase label, centred heading, centred paragraph, grid of identical
   cards) on a single flat ground. That repetition is what read as templated.
   ========================================================================== */

/* --- Grounds: step through the paper ladder so the page has rhythm ------- */
.section--p0 { background: var(--paper-0); }
.section--p1 { background: var(--paper-1); }
.section--p2 { background: var(--paper-2); }
.section--p3 { background: var(--paper-3); }

/* Vary the vertical measure too. Identical padding on every band is its own
   kind of monotony. Aim for one tall and one short per page, not more. */
.section--tall  { padding-block: calc(var(--sp-section) * 1.55); }
.section--short { padding-block: calc(var(--sp-section) * 0.5); }
.section--flush { padding-block: 0; }

/* --- Hand-rule instead of an eyebrow ------------------------------------
   The uppercase tracked label above every section is the most-flagged
   template tell there is, and at 12.5px it was also below our own type
   floor. A short rule marks the section start without saying anything. */
.rule-head { position: relative; padding-top: 1.5rem; }
.rule-head::before {
  content: "";
  position: absolute; top: 0; left: 0;
  width: 2.75rem; height: 2px;
  background: var(--clay-600);
}
.rule-head--center { text-align: center; }
.rule-head--center::before { left: 50%; transform: translateX(-50%); }

/* --- Metadata voice ------------------------------------------------------
   The third type role. Times, prices, the licence number, photo captions.
   This is what makes a page read like a record of a real house. */
.mono {
  font-family: var(--f-mono);
  font-size: .82rem;
  letter-spacing: .02em;
  color: var(--ink-soft);
}
.mono--lg { font-size: .95rem; }
.mono--tag {
  text-transform: uppercase;
  letter-spacing: .1em;
  font-size: .74rem;
  color: var(--clay-ink);
}

/* --- Definition run: replaces a grid of identical cards ------------------
   Most of what sat in cards was a list. A term plus a description, separated
   by a hairline in warm ink, is the print vocabulary that does the same job
   without boxing everything. */
.run { display: grid; gap: 0; margin: 0; }
.run > div {
  display: grid;
  grid-template-columns: minmax(9rem, 15ch) 1fr;
  gap: .6rem 2.5rem;
  padding-block: 1.5rem;
  border-bottom: 1px solid var(--rule-soft);
}
.run > div:first-child { border-top: 1px solid var(--rule-soft); }
.run dt {
  font-family: var(--f-mono);
  font-size: .8rem;
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: .07em;
  color: var(--forest-700);
  padding-top: .3em;
}
.run dd { margin: 0; max-width: 60ch; }
@media (max-width: 46em) {
  .run > div { grid-template-columns: 1fr; gap: .35rem; padding-block: 1.2rem; }
  .run dt { padding-top: 0; }
}

/* --- Checklist: "is this the right next step?" ---------------------------
   Meets the reader where she already is, before anything is sold. Marker is
   drawn rather than a bullet, and role="list" is required in the markup or
   Safari VoiceOver stops announcing it as a list once list-style is removed. */
.checklist { list-style: none; margin: 0; padding: 0; display: grid; gap: 1.05rem; }
.checklist li {
  position: relative;
  padding-left: 2.4rem;
  max-width: 58ch;
  font-size: 1.05rem;
}
.checklist li::before {
  content: "";
  position: absolute; left: 0; top: .28em;
  width: 1.25rem; height: 1.25rem;
  border: 2px solid var(--sage-500);
  border-radius: 3px;
}
.checklist li::after {
  content: "";
  position: absolute; left: .32rem; top: .55em;
  width: .58rem; height: .3rem;
  border-left: 2px solid var(--forest-700);
  border-bottom: 2px solid var(--forest-700);
  transform: rotate(-45deg);
}

/* --- Photo plates --------------------------------------------------------
   Every photograph gets its own aspect ratio via --ar. Uniform 4:3 crops are
   what make a gallery read as "assets in slots" rather than "photographs
   someone chose". Square corners: pictures in a house have square corners. */
.plate {
  margin: 0;
  background: var(--paper-2);
  padding: clamp(.5rem, 1.1vw, .85rem);
  border: 1px solid var(--rule-soft);
  border-radius: var(--r-plate);
  box-shadow: var(--sh-sm);
}
.plate img {
  display: block; width: 100%; height: 100%;
  aspect-ratio: var(--ar, 4 / 3);
  object-fit: cover;
  border-radius: 0;
}
.plate figcaption {
  font-family: var(--f-mono);
  font-size: .8rem;
  color: var(--ink-soft);
  margin-top: .75rem;
  padding-left: 1.5rem;
  position: relative;
  line-height: 1.5;
}
.plate figcaption::before {
  content: ""; position: absolute; left: 0; top: .62em;
  width: .95rem; height: 1px; background: var(--clay-600);
}

/* Two plates sharing a grid row, deliberately overlapped and offset. The
   vertical offset is what makes it read as placed rather than tiled. */
.plate-stack { display: grid; grid-template-columns: repeat(12, 1fr); align-items: start; }
.plate-stack > :nth-child(1) { grid-column: 1 / 8;  grid-row: 1; }
.plate-stack > :nth-child(2) { grid-column: 7 / 13; grid-row: 1; margin-top: 24%; z-index: 2; }
@media (max-width: 48em) {
  .plate-stack { display: grid; grid-template-columns: 1fr; gap: 1.5rem; }
  .plate-stack > :nth-child(1),
  .plate-stack > :nth-child(2) { grid-column: 1 / -1; grid-row: auto; margin-top: 0; }
}

/* Let one image cross the container edge. Nothing on the old page ever did,
   which is part of why it read as a template. */
.bleed {
  width: 100vw;
  margin-inline: calc(50% - 50vw);
  max-width: none;
}
.bleed img {
  width: 100%;
  aspect-ratio: var(--ar, 21 / 8);
  object-fit: cover;
  display: block;
}
@media (max-width: 48em) { .bleed img { aspect-ratio: 4 / 3; } }

/* --- Pull quote ---------------------------------------------------------- */
.pullquote {
  font-family: var(--f-display);
  font-style: italic;
  font-size: clamp(1.4rem, 2.4vw, 1.95rem);
  line-height: 1.34;
  color: var(--forest-800);
  max-width: 24ch;
  margin: 0;
  padding-top: 1.25rem;
  border-top: 2px solid var(--clay-600);
  /* italic descenders clip at tight leading */
  padding-bottom: .15em;
}

/* --- A number stated in prose, not in a stat tile ------------------------ */
.figure {
  font-family: var(--f-display);
  font-size: clamp(2.4rem, 5vw, 3.6rem);
  font-weight: 700;
  line-height: .95;
  color: var(--forest-700);
  display: block;
}

/* --- Soft divider between same-ground sections --------------------------- */
.divider {
  border: 0; height: 1px;
  background: var(--rule-soft);
  width: min(100%, 34rem);
  margin: clamp(2.5rem, 6vw, 4rem) 0;
}

/* ==========================================================================
   17c. PRICING COMPONENTS
   Added for the pricing page rebuild.

   The brief they answer: the old pricing page opened with three near-identical
   cards carrying a "Most common" badge. That is the SaaS pricing grid, and on
   a page whose entire argument is "we are a house, not a corporation" it was
   working directly against the copy. A family is not choosing a subscription
   tier. They are being quoted a rate for looking after their mother.

   So the vocabulary here is the rate card and the itemised statement: ruled
   rows, tabular figures, one number per line, nothing boxed.
   ========================================================================== */

/* --- Rate ladder: replaces the three pricing cards ----------------------- */
.tiers { display: grid; }
.tier {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 1.25rem 3.5rem;
  align-items: start;
  /* Three levels on one ruled list need real air between them or they read as
     one block of text. Roughly double the first pass. */
  padding-block: clamp(3rem, 5vw, 4.25rem);
  border-top: 1px solid var(--rule-soft);
}
.tier:last-child { border-bottom: 1px solid var(--rule-soft); }

.tier-label {
  font-family: var(--f-mono);
  font-size: .78rem;
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: .1em;
  color: var(--clay-ink);
  margin-bottom: .3rem;
}
/* Level 2 is where most residents start. That is worth saying, but as a note
   in the margin rather than a "Most popular" badge, which is a sales device
   from a different kind of business. */
.tier-note {
  font-family: var(--f-mono);
  font-size: .78rem;
  color: var(--clay-ink);
  margin: -.15rem 0 .55rem;
}
.tier h3 { font-size: clamp(1.35rem, 2.2vw, 1.6rem); margin-bottom: .45rem; }
.tier-who { color: var(--ink-body); max-width: 46ch; margin-bottom: .9rem; }
.tier-adds { margin: 0; max-width: 52ch; font-size: .98rem; color: var(--ink-soft); }
.tier-adds b {
  display: block;
  font-family: var(--f-mono);
  font-size: .76rem;
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: .08em;
  color: var(--forest-700);
  margin-bottom: .3rem;
}

.tier-price { display: grid; justify-items: end; text-align: right; }
.tier-price b {
  font-family: var(--f-display);
  font-size: clamp(2.1rem, 3.6vw, 2.85rem);
  font-weight: 700;
  line-height: 1;
  color: var(--forest-800);
  font-variant-numeric: tabular-nums;
}
.tier-price .per {
  font-family: var(--f-mono);
  font-size: .8rem;
  color: var(--ink-soft);
  margin: .5rem 0 1.1rem;
}
.tier-price .btn { white-space: nowrap; }

@media (max-width: 46em) {
  .tier { grid-template-columns: 1fr; gap: 1.35rem; }
  .tier-price { justify-items: start; text-align: left; }
  .tier-price .btn { width: 100%; text-align: center; }
}

/* --- Itemised statement --------------------------------------------------
   The whole cost of a month, written out. This is the page's argument as an
   object: if there is nothing hidden, you can show the entire bill. */
.receipt {
  max-width: 36rem;
  border-top: 2px solid var(--forest-700);
}
.receipt-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: .5rem 1.5rem;
  align-items: baseline;
  padding-block: .95rem;
  border-bottom: 1px solid var(--rule-soft);
}
.receipt-row .k { margin: 0; font-size: 1rem; color: var(--ink-body); }
.receipt-row .k small {
  display: block;
  font-family: var(--f-mono);
  font-size: .76rem;
  color: var(--ink-soft);
  margin-top: .2rem;
}
.receipt-row .v {
  margin: 0;
  font-family: var(--f-mono);
  font-size: 1.02rem;
  font-variant-numeric: tabular-nums;
  color: var(--forest-800);
  white-space: nowrap;
}
.receipt-row--sum {
  border-bottom: 0;
  border-top: 2px solid var(--forest-700);
  margin-top: .35rem;
  padding-top: 1.1rem;
}
.receipt-row--sum .k { font-weight: 700; color: var(--ink); }
.receipt-row--sum .v { font-weight: 500; font-size: 1.15rem; }

/* --- Money-first definition run ------------------------------------------
   For the fee schedule. Putting the figure in the left column means the
   answer to "what does this cost" arrives before the explanation. */
.run--money > div { grid-template-columns: minmax(7.5rem, 12ch) 1fr; }
.run--money dt {
  font-family: var(--f-mono);
  font-size: 1rem;
  letter-spacing: 0;
  text-transform: none;
  font-variant-numeric: tabular-nums;
  color: var(--forest-800);
  padding-top: .12em;
}
.run--money dd b { color: var(--ink); }
.run--money dd small {
  display: block;
  font-size: .92rem;
  color: var(--ink-soft);
  margin-top: .2rem;
}
@media (max-width: 46em) {
  .run--money > div { grid-template-columns: 1fr; }
  .run--money dt { padding-top: 0; }
}

/* --- Editorial components on the dark band ------------------------------- */
.section--forest .run > div { border-color: rgba(255,255,255,.2); }
.section--forest .run dt { color: var(--sage-200); }
.section--forest .run dd { color: #CFDDCE; }
.section--forest .rule-head::before { background: var(--sage-300); }
.section--forest .mono { color: var(--sage-200); }
.section--forest p { color: #CFDDCE; }
/* `strong` is forest-900 globally, which is 1.21:1 on this band. Emphasis on a
   dark ground has to brighten, not darken. Same for `b`, which is used for
   labels inside .tier-adds and .run--money. */
.section--forest strong,
.section--forest b { color: var(--paper-0); }
.section--forest .pullquote {
  color: var(--paper-0);
  border-color: var(--sage-300);
}
/* Inline links inherit --forest-700, which is invisible on a forest ground.
   paper-0 measures 8.28:1 against the lightest end of the band, and the
   underline from the base `a` rule carries the affordance either way. */
/* :not(.btn) is load-bearing. Without it this rule outranks .btn--light's own
   colour (it is more specific AND later in the file), so a light button on a
   dark band rendered white text on a white fill: invisible until hover. */
.section--forest a:not(.btn) { color: var(--paper-0); }
.section--forest a:not(.btn):hover { color: var(--sage-200); }

/* Anchor targets sit under the sticky header without this. Other pages link
   to #level-1 / #level-2 / #level-3. */
.tier[id] { scroll-margin-top: calc(var(--nav-h) + 1.5rem); }

/* ==========================================================================
   18. CROSS-BROWSER + RESPONSIVE HARDENING
   Everything below exists to make the site behave identically on iOS Safari,
   Android Chrome, desktop Safari/Chrome/Firefox/Edge, from 320px phones to
   4K monitors, in portrait and landscape.
   ========================================================================== */

/* --- 18.1 Never allow a horizontal scrollbar -----------------------------
   `clip` is used instead of `hidden` because it does not create a scroll
   container, so the sticky header keeps working. Browsers without `clip`
   (Safari < 16) fall back to the source-level fixes, which are enough. */
@supports (overflow: clip) {
  html, body { overflow-x: clip; }
}

/* --- 18.2 Nothing may overflow its container ---------------------------- */
/* Long words, emails and unbroken strings wrap instead of pushing the page
   sideways. Critical at 320px, where "caregiver-to-resident" would overflow. */
body, p, li, h1, h2, h3, h4, blockquote, dd, dt, figcaption, label, .lead {
  overflow-wrap: break-word;
  word-wrap: break-word;
}

/* Grid and flex children default to min-width:auto, which lets wide content
   (tables, long words, images) blow out the track. This is the standard fix. */
.grid > *, .split > *, .hero-grid > *, .price-grid > *, .gallery > *,
.contact-grid > *, .stat-grid > *, .footer-top > *, .footer-links > *, .btn-row > *,
.trustbar .row > * {
  min-width: 0;
}

/* Media never exceeds its box, whatever the intrinsic size. */
img, picture, svg, video, iframe, table { max-width: 100%; }
iframe { border: 0; }

/* --- 18.3 Hero: fits every screen -------------------------------------- */
.hero {
  /* Clips the decorative frame and the floating ratio card so neither can
     ever create horizontal scroll, at any width. */
  overflow: hidden;
  /* Belt-and-braces against sub-pixel rounding on Android Chrome. */
  max-width: 100%;
}

/* On a desktop-sized screen that is also tall enough, the hero fills the
   viewport below the nav and centres its content. Guarded by BOTH a width and
   a height query so it never applies to a landscape phone, where forcing
   viewport height would crush the headline. */
@media (min-width: 900px) and (min-height: 660px) {
  .hero {
    display: flex;
    align-items: center;
    min-height: calc(100vh - var(--nav-h));
  }
  .hero > .container { width: min(100% - 2.5rem, var(--container)); }
}

/* Desktop hero sizing.
   A real browser window is 150-200px shorter than the screen once tabs, the
   URL bar and bookmark bars are accounted for. A 1440x900 display is often a
   1440x700 viewport. These values keep the headline, the paragraph and the
   "Schedule a Free Tour" button inside that, rather than pushing the button
   below the fold. */
@media (min-width: 900px) {
  .hero { padding-block: 2.75rem 3.25rem; }
  .hero .availability { margin-bottom: 1rem; }
  .hero h1 {
    font-size: clamp(2.5rem, 3.6vw, 3.25rem);
    line-height: 1.08;
    margin-bottom: .85rem;
  }
  .hero p.lead { margin-bottom: 1.5rem; max-width: 31rem; }
  /* Give the text column the extra width, since it is the part that wraps. */
  .hero-grid { grid-template-columns: 1.12fr .88fr; gap: clamp(1.75rem, 3.5vw, 3.25rem); }
}

/* Short desktop viewports (most laptops in the real world). Trims further so
   the call to action stays visible without scrolling. */
@media (min-width: 900px) and (max-height: 820px) {
  .hero { padding-block: 2rem 2.5rem; min-height: 0; }
  .hero h1 { font-size: clamp(2.3rem, 3.1vw, 2.9rem); }
  .hero p.lead { font-size: 1.08rem; line-height: 1.6; margin-bottom: 1.25rem; }
  .hero .btn--lg { min-height: 54px; font-size: 1.05rem; }
  .hero .availability { margin-bottom: .8rem; }
}

/* Very short desktop viewports (a small laptop window, or lots of toolbars). */
@media (min-width: 900px) and (max-height: 700px) {
  .hero { padding-block: 1.5rem 2rem; }
  .hero h1 { font-size: clamp(2.1rem, 2.8vw, 2.6rem); margin-bottom: .7rem; }
  .hero p.lead { font-size: 1.03rem; margin-bottom: 1.1rem; }
}
/* svh accounts for the iOS/Android collapsing address bar, so the hero does
   not jump as the bar hides. Applied only where supported. */
@supports (height: 100svh) {
  @media (min-width: 900px) and (min-height: 660px) {
    .hero { min-height: calc(100svh - var(--nav-h)); }
  }
}

/* Headline balances across lines rather than leaving one orphan word.
   Progressive enhancement: ignored where unsupported. */
.hero h1, .page-header h1, .section-head h2, .cta-band h2 {
  text-wrap: balance;
}

/* Phones: tighten the hero's vertical rhythm so the primary call to action
   lands above the fold on a standard phone rather than below it. */
@media (max-width: 700px) {
  .hero { padding-block: 2rem 2.5rem; }
  .hero .availability { margin-bottom: 1rem; }
  .hero h1 { margin-bottom: .8rem; line-height: 1.12; }
  .hero p.lead { font-size: 1.02rem; line-height: 1.55; margin-bottom: 1.4rem; }
  .hero .btn-row { gap: .7rem; }
  .hero .btn-row .btn { width: 100%; }
  .hero-media { margin-top: 1.75rem; }
}

/* Small phones (320 to 400px): trim the decorative extras that cost width. */
@media (max-width: 400px) {
  .hero { padding-block: 1.5rem 2rem; }
  .hero h1 { font-size: clamp(1.85rem, 9vw, 2.2rem); }
  .hero p.lead { font-size: .98rem; line-height: 1.5; margin-bottom: 1.2rem; }
  .hero .btn--lg { min-height: 54px; font-size: 1.03rem; }
  .hero-media::after { display: none; }
  .hero-float { left: 6px; bottom: 6px; max-width: min(74%, 200px); padding: .6rem .8rem; }
  .hero-float .big { font-size: 1.4rem; }
  .hero-float .cap { font-size: .76rem; }
  .availability { font-size: .74rem; }
  .container, .container--narrow { width: min(100% - 1.75rem, var(--container)); }
}

/* Very small phones (320px: iPhone SE 1st gen, older Android).
   Squeezed hard so the "Schedule a Free Tour" button still lands above the
   fold on a 568px-tall screen, which is the shortest phone still in use. */
@media (max-width: 340px) {
  .hero-float { position: static; margin-top: .85rem; max-width: none; box-shadow: var(--sh-sm); }
  .btn { padding-inline: 1.25rem; font-size: .97rem; }
  .btn--lg { padding-inline: 1.4rem; font-size: 1.02rem; }

  .hero { padding-block: 1rem 1.5rem; }
  .hero .availability { font-size: .7rem; margin-bottom: .7rem; }
  .hero h1 { font-size: 1.72rem; margin-bottom: .6rem; }
  .hero p.lead { font-size: .92rem; line-height: 1.45; margin-bottom: 1rem; }
  .hero .btn--lg { min-height: 48px; }
  .hero .btn-row { gap: .6rem; }
}

/* --- Short-viewport hero rules ------------------------------------------
   These come LAST on purpose. They are height-based, and the width-based
   blocks above would otherwise win on source order and undo them. */

/* Short phone viewports. An iPhone SE 1st gen leaves about 505px of usable
   height once Safari's chrome is subtracted. The "Now accepting new residents"
   chip is marketing garnish, so it yields to keep the primary button visible. */
@media (max-width: 500px) and (max-height: 580px) {
  .hero { padding-block: .6rem 1.1rem; }
  .hero .availability { display: none; }
  .hero h1 { font-size: 1.55rem; line-height: 1.07; margin-bottom: .5rem; }
  .hero p.lead { font-size: .87rem; line-height: 1.38; margin-bottom: .8rem; }
  .hero .btn--lg { min-height: 46px; font-size: .97rem; }
  .hero .btn-row { gap: .5rem; }
  .hero-media { margin-top: 1rem; }
}

/* Landscape phones leave roughly 320px of vertical space once the sticky call
   bar is subtracted. Shrinking type alone cannot win that, so the layout
   changes instead: the decorative hero photo steps aside and the text runs
   full width, which cuts the headline and paragraph to far fewer lines. The
   photo is not lost, it is simply not in the hero in this orientation. */
@media (max-height: 500px) and (orientation: landscape) {
  .hero { padding-block: 1rem 1.25rem; min-height: 0; display: block; }
  .hero .availability { display: none; }
  .hero-grid { grid-template-columns: 1fr; gap: 0; }
  .hero-media { display: none; }
  .hero h1 { font-size: clamp(1.5rem, 3.4vw, 2rem); line-height: 1.06; margin-bottom: .5rem; }
  .hero p.lead { font-size: .95rem; line-height: 1.45; margin-bottom: .9rem; max-width: none; }
  .hero .btn-row .btn { width: auto; }
  .hero .btn--lg { min-height: 46px; padding-block: .55rem; font-size: 1rem; }
  .mobile-menu { padding-bottom: 4rem; }
}

/* Fallback for browsers without aspect-ratio (Safari < 15): keeps the hero
   and gallery images from collapsing to zero height. */
@supports not (aspect-ratio: 4 / 3) {
  .hero-media img { height: 320px; object-fit: cover; }
  .gal-item img { height: 240px; object-fit: cover; }
  .media-frame img { height: 320px; object-fit: cover; }
}

/* --- 18.4 `inset` shorthand fallback (Safari < 14.1) -------------------- */
.lightbox { top: 0; right: 0; bottom: 0; left: 0; }
.mobile-menu { top: var(--nav-h); right: 0; bottom: 0; left: 0; }
.hero-media::after { right: -14px; bottom: -14px; }

/* --- 18.5 Touch behaviour ---------------------------------------------- */
/* Removes the grey flash Android/iOS paint over tapped elements. */
a, button, .btn, .gal-item, .faq-q, .nav-toggle {
  -webkit-tap-highlight-color: rgba(45, 84, 64, .12);
}
/* Momentum scrolling for the wide comparison table on iOS. */
.compare-wrap { -webkit-overflow-scrolling: touch; overscroll-behavior-x: contain; }

/* Every interactive target meets the 44x44px minimum on touch devices. */
@media (hover: none) and (pointer: coarse) {
  .nav-links a, .submenu a, .mobile-menu a { min-height: 44px; display: flex; align-items: center; }
  .mobile-menu .m-sub a { min-height: 44px; }
  .faq-q { min-height: 56px; }
  /* Hover lifts are meaningless on touch and can leave elements stuck raised. */
  .btn:hover, .card:hover, .gal-item:hover img { transform: none; }
}

/* The rules above key off `pointer: coarse`, which a narrow desktop window
   does not match. These are width-based so standalone links are comfortably
   tappable on any small screen, however the browser reports itself.
   Footer link gaps tighten to absorb the extra height. */
@media (max-width: 780px) {
  .site-footer ul { gap: 0; }
  .site-footer ul a,
  /* flex, not inline-flex: inline-flex put the phone number and the email
     address on the same line on every phone. Block-level keeps them stacked
     and still gives each a 44px target. */
  .footer-contact > a {
    display: flex;
    align-items: center;
    min-height: 44px;
  }
  .contact-item a {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-height: 44px;
  }
  /* Breadcrumbs: WCAG 2.5.8 asks for 24px minimum on AA. */
  .crumbs a { display: inline-block; padding-block: .3rem; }
  /* The inline phone number in body copy is a primary action on mobile. */
    /* Bigger tap target for a phone number sitting inline in prose.
       Scoped to prose containers on purpose. The earlier bare
       a[href^="tel:"] captured .btn and killed its flex centring; adding
       :not(.btn) then pushed the selector to (0,2,1), which outranked
       `.nav-cta .nav-phone { display:none }` and put the header phone number
       back on mobile, shoving the hamburger clean off the screen. Narrow
       beats specific. */
    p a[href^="tel:"]:not(.btn),
    li a[href^="tel:"]:not(.btn),
    dd a[href^="tel:"]:not(.btn),
    td a[href^="tel:"]:not(.btn),
    address a[href^="tel:"]:not(.btn) { display: inline-block; padding-block: .25rem; }
  .footer-bottom a { padding-block: .3rem; display: inline-block; }
  /* Phone and email links inside the referral placement table. */
  table.compare td a { display: inline-block; padding-block: .35rem; }
}

/* --- 18.6 Forms on iOS -------------------------------------------------- */
/* Any input under 16px makes iOS Safari zoom the page on focus. These are all
   at or above 16px, and this locks that in. */
input, select, textarea, button { font-size: max(16px, 1rem); }

/* iOS applies its own rounded/inset styling to inputs. Reset it so fields
   look the same on every platform. `date` keeps its native picker. */
.field input, .field textarea, .field select {
  -webkit-appearance: none;
  appearance: none;
  border-radius: var(--r-sm);
}
.field input[type="date"] {
  -webkit-appearance: none;
  min-height: 52px;
  /* Safari on iOS otherwise vertically mis-aligns the date text. */
  display: block;
  text-align: left;
}
/* Custom chevron, since appearance:none removes the native one. */
.field select {
  background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' fill='none'%3E%3Cpath d='M1 1l5 5 5-5' stroke='%232D5440' stroke-width='1.8' stroke-linecap='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 1rem center;
  padding-right: 2.75rem;
}
/* Firefox: hide the inner focus ring on selects. */
.field select:-moz-focusring { color: transparent; text-shadow: 0 0 0 var(--ink); }

/* --- 18.7 Tablets (768 to 1080px) --------------------------------------- */
/* The nav collapses to the hamburger at 1080px, so this range is the iPad
   window. Two-column grids read better than three here. */
@media (min-width: 700px) and (max-width: 1080px) {
  .grid-3 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .price-grid { grid-template-columns: repeat(auto-fit, minmax(min(100%, 260px), 1fr)); }
  /* The footer manages its own columns in both its rows; forcing 2 here
     collapsed five link groups into a tall stack. */
  .footer-links { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

/* --- 18.8 Large and ultra-wide screens ---------------------------------- */
@media (min-width: 1600px) {
  :root { --container: 1320px; }
  body { font-size: 1.09rem; }
}
@media (min-width: 2200px) {
  :root { --container: 1440px; }
}

/* --- 18.9 Notched phones ------------------------------------------------ */
/* Keeps content clear of the rounded corners and home indicator in landscape
   on iPhone X and later. */
@supports (padding: max(0px)) {
  .container, .container--narrow {
    padding-left: max(0px, env(safe-area-inset-left));
    padding-right: max(0px, env(safe-area-inset-right));
  }
  .mobile-bar {
    padding-left: max(.9rem, env(safe-area-inset-left));
    padding-right: max(.9rem, env(safe-area-inset-right));
  }
}

/* --- 18.10 Windows / Android font rendering ----------------------------- */
/* Playfair at large sizes can render thin on Windows. Nudge the weight. */
@media screen and (-ms-high-contrast: active), (-ms-high-contrast: none) {
  h1, h2 { font-weight: 700; }
}

/* --- 18.11 Forced-colours / high-contrast mode -------------------------- */
@media (forced-colors: active) {
  .btn { border: 2px solid currentColor; }
  .card, .price-card, .faq-item, .compare-wrap { border: 1px solid currentColor; }
  .checks li::after { border-color: currentColor; }
}

/* --- 18.12 Keyboard focus for older Safari ------------------------------ */
/* Safari < 15.4 has no :focus-visible. Give those users a visible ring. */
@supports not selector(:focus-visible) {
  a:focus, button:focus, input:focus, select:focus, textarea:focus {
    outline: 3px solid var(--clay-500);
    outline-offset: 3px;
  }
}
