/* The hidden attribute means hidden, whatever else a selector says.
   Without this a rule that sets display on an element type quietly
   outranks it, because [hidden] is one attribute against a class or a
   type plus attribute. That is how a date picker stayed on screen next
   to the Sold out field that had just replaced it. Three rules further
   down patch single cases of the same thing and predate this; they are
   left alone because they are correct, not because they are needed. */
[hidden] { display: none !important; }
.skip-link { position: absolute; left: -9999px; top: 0; z-index: 100;
  background: var(--brass); color: var(--charcoal); font-weight: 700;
  padding: 10px 18px; border-radius: 0 0 6px 0; text-decoration: none; }
.skip-link:focus { left: 0; }
/* The app tab bar exists in the markup at every width and only the
   phone block ever displays it. */
#pw-tabbar { display: none; }

/* StoreWelly brand system
   Charcoal and parchment carry the interface. Deep green is the brand
   signature, champagne brass is reserved for primary actions and premium
   detail. Stone, terracotta and moss are functional states only. */

:root {
  --charcoal: #111312;
  --charcoal-soft: #1b1e1c;
  --green: #163F32;
  --green-bright: #1e5643;
  --brass: #D6B77B;
  --brass-deep: #c2a05f;
  --parchment: #EFE8DA;
  --porcelain: #F7F3EB;
  /* Darkened from #7A7D75 (2026-08-28): as text on parchment it
     measured 3.43:1 against WCAG's 4.5:1, meaning every .sub line,
     card meta row and form hint was formally too faint to read.
     #64675F is the closest grey-green that passes on both grounds
     (4.72:1 on parchment, 5.20:1 on porcelain). */
  --stone: #64675F;
  --terracotta: #B84C3A;
  --moss: #7A9652;
  --serif: "Fraunces", Georgia, serif;
  --sans: "Inter", -apple-system, "Segoe UI", sans-serif;
}

* { margin: 0; padding: 0; box-sizing: border-box; }

html { scroll-behavior: smooth; }

/* Touch only, so inert on laptops: a tap highlight never paints for a
   mouse. Without this every tap flashes the browser's default grey,
   which reads as somebody else's UI on the charcoal header and the
   brass buttons; a faint brass flash answers in the house palette. */
html { -webkit-tap-highlight-color: rgba(214, 183, 123, 0.22); }

/* The iOS app adds this class from its own user agent marker. The
   rubber band bounce dragged the sticky header off the top of the
   screen, which in an app reads as broken rather than playful, so the
   root scroller refuses to overscroll there. Browsers never get the
   class, so Safari and Chrome keep their native feel. */
html.app-shell { overscroll-behavior-y: none; background: var(--charcoal); }
html.app-shell body { overscroll-behavior-y: none; }

/* The opening moment. Only ever unhidden inside the app shell, once
   per launch: the native splash hands over to this identical charcoal
   frame, the mark holds for a beat, then rises away as the page
   reveals underneath. The overlay's own fade is the removal cue for
   the script, and a reduced-motion open is a plain quick fade. */
#app-open {
  position: fixed;
  inset: 0;
  z-index: 4000;
  background: var(--charcoal);
  display: flex;
  align-items: center;
  justify-content: center;
  animation: app-open-out 0.4s ease 0.85s forwards;
}
.app-open-inner {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 16px;
  animation: app-open-rise 0.6s cubic-bezier(0.22, 1, 0.36, 1) 0.45s forwards;
}
.app-open-inner img { border-radius: 20px; }
.app-open-word { font-family: var(--serif); font-size: 32px; letter-spacing: 0.01em; }
.app-open-word .park { color: var(--porcelain); }
.app-open-word .welly { color: var(--brass); }
@keyframes app-open-rise {
  to { transform: translateY(-18vh) scale(0.7); opacity: 0; }
}
@keyframes app-open-out {
  to { opacity: 0; visibility: hidden; }
}
@media (prefers-reduced-motion: reduce) {
  #app-open { animation: app-open-out 0.25s ease 0.3s forwards; }
  .app-open-inner { animation: none; }
}
/* While the opening curtain is up the page is frozen at the top, so a
   restored scroll position cannot flash old content under it. */
html.app-opening, html.app-opening body { overflow: hidden; height: 100%; }
/* Inside the shell the header is viewport-anchored, not scroller
   anchored: sticky elements ride the rubber band, fixed ones hold.
   The script measures the real header height into the body padding.
   The native half (scrollView.bounces = false) lands with the next
   app build; this keeps the header still until then. */
html.app-shell .site-header { position: fixed; left: 0; right: 0; top: 0; }

body {
  font-family: var(--sans);
  background: var(--parchment);
  color: var(--charcoal);
  line-height: 1.6;
  font-size: 16px;
}

img { max-width: 100%; display: block; }
a { color: inherit; }

.wrap { max-width: 1120px; margin: 0 auto; padding: 0 24px; }
.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; }

h1, h2, h3, .serif { font-family: var(--serif); font-weight: 500; line-height: 1.12; }

.eyebrow {
  font-size: 12px;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--brass);
  font-weight: 600;
  margin-bottom: 18px;
}

/* Header */
.site-header {
  background: var(--charcoal);
  color: var(--porcelain);
  border-bottom: 1px solid rgba(214, 183, 123, 0.25);
  position: sticky;
  top: 0;
  z-index: 1000;
  /* The iOS app and an installed PWA draw edge to edge, so the header
     steps around the clock and the Dynamic Island. env() is zero in
     every ordinary browser and on every laptop, so this is inert
     outside those shells, which is also why it lives here rather than
     in the phone block: an iPad running the app is wider than 880px
     and needs it just the same. The bottom inset twins (the book bar
     and the map card) already pad the same way. */
  padding-top: env(safe-area-inset-top, 0px);
}
.site-header .wrap {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
  min-height: 72px;
  max-width: none;
}
.wordmark {
  font-family: var(--serif);
  font-size: 26px;
  text-decoration: none;
  letter-spacing: 0.01em;
  white-space: nowrap;
  display: inline-flex;
  align-items: center;
}
.logo-mark { width: 40px; height: 40px; margin-right: 12px; }
.site-footer .wordmark .logo-mark { width: 34px; height: 34px; }
.wordmark .park { color: var(--porcelain); }
.wordmark .welly { color: var(--brass); }
.main-nav { display: flex; align-items: center; gap: 22px; flex-wrap: wrap; }
.head-right { display: flex; align-items: center; gap: 18px; }
/* One door for everybody who is not signed in. Solid brass, because it
   is the only thing in the header asking to be pressed. */
.my-storewelly {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  background: var(--brass);
  color: var(--charcoal);
  font-family: var(--sans);
  font-size: 14.5px;
  font-weight: 700;
  letter-spacing: 0.01em;
  text-decoration: none;
  padding: 9px 18px;
  border-radius: 3px;
  white-space: nowrap;
  transition: background 0.15s ease;
}
.my-storewelly:hover { background: var(--porcelain); }
.my-storewelly svg { width: 17px; height: 17px; flex: none; }
/* Wide screens have the room, so the controls are simply always there
   and the summary line is not rendered at all. */
.search-more-toggle { display: none; }
/* Both of these only exist on a phone. A wide screen shows the map and
   the list side by side, so there is nothing to choose between. */
.view-toggle { display: none; }
.side-search-bar { display: contents; }
/* Two of these only exist at one width or the other. Sign up sits beside
   Log in on a wide screen and inside the burger on a narrow one, so
   whichever is showing is the only one in the accessibility tree. */
.in-burger { display: none; }
.burger { display: none; }
.main-nav a {
  color: var(--porcelain);
  text-decoration: none;
  font-size: 14.5px;
  letter-spacing: 0.01em;
  font-weight: 600;
  opacity: 0.9;
  white-space: nowrap;
}
.main-nav a:hover { color: var(--brass); opacity: 1; }
.main-nav a.nav-cta {
  border: 1px solid var(--brass);
  color: var(--brass);
  padding: 8px 16px;
  border-radius: 3px;
}
.main-nav a.nav-cta:hover { background: var(--brass); color: var(--charcoal); }
/* Account menu: brass box with hover dropdown */
.user-menu { position: relative; }
.user-box {
  display: inline-block;
  background: var(--brass);
  color: var(--charcoal) !important;
  font-weight: 700;
  padding: 9px 18px;
  border-radius: 3px;
  text-decoration: none;
  font-size: 14.5px;
}
.user-box:hover { background: var(--brass-deep); color: var(--charcoal); }
/* The menu forgives a wandering cursor: it holds for a beat after the
   pointer leaves, and the transparent padding bridges the gap between
   the button and the list so a diagonal exit does not close it.
   visibility rather than display, because display cannot be delayed. */
.user-drop {
  visibility: hidden;
  opacity: 0;
  position: absolute;
  right: -12px;
  top: 100%;
  padding: 12px 12px 14px;
  min-width: 220px;
  z-index: 1100;
  transition: visibility 0s linear 0.45s, opacity 0.14s ease 0.31s;
}
.user-menu:hover .user-drop, .user-menu:focus-within .user-drop,
.user-drop:hover {
  visibility: visible;
  opacity: 1;
  transition: visibility 0s, opacity 0.12s ease;
}
.user-drop > a, .user-drop button {
  display: block;
  width: 100%;
  text-align: left;
  background: var(--charcoal);
  color: var(--porcelain);
  border: 1px solid rgba(214, 183, 123, 0.35);
  border-top: none;
  padding: 11px 16px;
  font-size: 14px;
  font-weight: 600;
  text-decoration: none;
  font-family: var(--sans);
  cursor: pointer;
}
.user-drop > a:first-child { border-top: 2px solid var(--brass); border-radius: 3px 3px 0 0; }
.user-drop form { margin: 0; }
.user-drop button { border-radius: 0 0 3px 3px; color: var(--terracotta); }
.user-drop > a:hover, .user-drop button:hover { background: var(--green); color: var(--brass); }

.nav-badge {
  display: inline-block;
  background: var(--terracotta);
  color: var(--porcelain);
  border-radius: 9px;
  font-size: 10px;
  padding: 1px 6px;
  margin-left: 4px;
  vertical-align: middle;
}

/* Buttons */
.btn {
  display: inline-block;
  background: var(--brass);
  color: var(--charcoal);
  font-family: var(--sans);
  font-size: 15px;
  font-weight: 700;
  letter-spacing: 0.02em;
  text-decoration: none;
  border: none;
  border-radius: 3px;
  padding: 14px 26px;
  /* anchors inherit the page line-height while buttons default to their
     own, which made a-buttons and button-buttons different heights */
  line-height: 1.4;
  cursor: pointer;
}
.btn:hover { background: var(--brass-deep); }
.btn-outline {
  background: transparent;
  border: 1px solid var(--brass);
  color: var(--brass);
}
.btn-outline:hover { background: var(--brass); color: var(--charcoal); }
.btn-dark { background: var(--green); color: var(--porcelain); }
.btn-dark:hover { background: var(--green-bright); }
.btn-small { padding: 8px 15px; font-size: 13px; }
.btn-danger { background: transparent; border: 1px solid var(--terracotta); color: var(--terracotta); }
.btn-danger:hover { background: var(--terracotta); color: var(--porcelain); }

/* Hero */
.hero {
  background: var(--charcoal);
  color: var(--porcelain);
  position: relative;
}
.hero .wrap { position: relative; z-index: 2; }
.hero-video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: 0.22;
  filter: saturate(0.65);
  z-index: 0;
  pointer-events: none;
}
.hero-shade {
  position: absolute;
  inset: 0;
  z-index: 1;
  background: linear-gradient(180deg,
    rgba(17, 19, 18, 0.55) 0%,
    rgba(17, 19, 18, 0.25) 45%,
    rgba(17, 19, 18, 0.75) 100%);
}
@media (prefers-reduced-motion: reduce) {
  .hero-video { display: none; }
}
.hero-inner {
  max-width: 680px;
  padding: 110px 0 84px;
}
.hero h1 {
  font-size: clamp(44px, 6.5vw, 76px);
  color: var(--porcelain);
  margin-bottom: 12px;
}
.hero p.lede {
  color: rgba(247, 243, 235, 0.75);
  font-size: 18px;
  max-width: 34em;
  margin-bottom: 36px;
}
/* Search panel */
.search-panel {
  background: var(--porcelain);
  border: 1px solid var(--brass);
  border-radius: 4px;
  display: grid;
  grid-template-columns: 1.4fr 1fr 1fr auto;
  margin-bottom: 20px;
}
/* Hourly/daily swaps the single date for two combined date-and-time
   pickers; the column plan changes with it so everything stays on one
   line on a laptop. Hidden fields leave the grid entirely. */
.search-panel.short { grid-template-columns: 1.2fr 0.9fr 1.15fr 1.15fr auto; }
.search-panel .field[hidden] { display: none; }
.search-panel input[type=date],
.search-panel input[type=datetime-local] {
  -webkit-appearance: none;
  appearance: none;
  display: block;
  max-width: 100%;
  min-width: 0;
}
.search-panel input[type=datetime-local] {
  font-family: var(--sans);
  font-size: 15px;
  padding-top: 4px;
}
@media (max-width: 900px) {
  .search-panel, .search-panel.short { grid-template-columns: 1fr; }
  .search-panel .field { border-right: none; border-bottom: 1px solid rgba(17, 19, 18, 0.12); }
  .search-panel .search-btn { grid-column: 1 / -1; }
}
.search-panel .field {
  padding: 18px 22px;
  border-right: 1px solid rgba(17, 19, 18, 0.12);
}
.search-panel label {
  display: block;
  font-size: 11px;
  letter-spacing: 0.04em;
  color: var(--stone);
  font-weight: 700;
  margin-bottom: 4px;
}
.search-panel input, .search-panel select {
  font-family: var(--serif);
  font-size: 20px;
  border: none;
  background: transparent;
  color: var(--charcoal);
  width: 100%;
  outline: none;
}
/* The hint must fit whatever the grid mode: typed text can scroll, a
   cut-off placeholder just looks broken. */
.search-panel input::placeholder { font-size: 16px; }
/* The panel's dropdown wears the house brass triangle, not the
   browser's chevron. After the rule above: its background shorthand
   would otherwise wipe the image. */
.search-panel select {
  appearance: none;
  -webkit-appearance: none;
  padding-right: 30px;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='7'%3E%3Cpath d='M0 0h10L5 7z' fill='%23D6B77B'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 14px center;
  background-size: 10px 7px;
}
.search-panel .search-btn {
  margin: 10px;
  align-self: stretch;
  display: flex;
}
.search-panel .search-btn button { flex: 1; }
.hero .search-panel { margin-bottom: 72px; }
.hero-boot {
  font-family: var(--serif);
  font-size: clamp(20px, 2.6vw, 30px);
  color: var(--brass);
  margin: 4px 0 26px;
}

/* The app in the hero (Henry, 2026-09-10). The wrap becomes a grid of
   two rows: the copy and the phone side by side, the search panel the
   full width under both. The phone is a screenshot in a CSS bezel
   rather than a picture of a phone, so the same file serves the hero
   and the app section at different sizes and never carries a frame
   of its own. The aside's width follows the viewport, 340 to 470px,
   because an auto column takes its max-content width and the headline
   then broke "People powered" over two lines at 881px; bounded, the
   copy keeps at least the width the headline needs at every laptop
   width. The phone is capped at 228px so the hero is no taller than
   it was: the copy's own padding contains it. */
.hero .wrap {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  grid-template-areas: "copy app" "search search";
  column-gap: 32px;
  align-items: end;
}
.hero-inner { grid-area: copy; }
.hero .search-panel { grid-area: search; }
.hero-app {
  grid-area: app;
  display: flex;
  align-items: flex-end;
  justify-content: flex-end;
  gap: 28px;
  width: clamp(340px, 40vw, 470px);
  padding-bottom: 84px;
}
.hero-app-copy {
  flex: 1 1 auto;
  min-width: 0;
  text-align: right;
  color: rgba(247, 243, 235, 0.78);
  font-size: 15px;
  line-height: 1.5;
}
.hero-app-copy .eyebrow { margin-bottom: 10px; }
.hero-app-copy p { margin: 0; }
/* Apple's badge, used as supplied. The anchor is the whole target and
   the image is its only content, so the anchor takes no line box of
   its own. */
.store-badge { display: inline-block; line-height: 0; border-radius: 6px; }
.store-badge img { height: 44px; width: auto; }
.store-badge:focus-visible { outline: 2px solid var(--brass); outline-offset: 3px; }
.hero-app-copy .store-badge { margin-top: 18px; }
.app-phone {
  flex: none;
  width: clamp(176px, 18vw, 228px);
  padding: 8px;
  background: #1d1f1e;
  border-radius: 34px;
  box-shadow: 0 0 0 1px rgba(214, 183, 123, 0.45), 0 30px 60px rgba(0, 0, 0, 0.55);
}
.app-phone img { width: 100%; height: auto; border-radius: 26px; }

/* The app section: the screens side by side, one line under each,
   the badge once more underneath. The columns follow the cards (two
   today, three once the hosting screen is shot as a host), and the
   grid is bounded so two phones sit near each other rather than at
   the far ends of the wrap. */
.app-grid {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: minmax(0, 1fr);
  gap: 36px;
  align-items: start;
  max-width: 900px;
  margin: 0 auto;
}
.app-card { margin: 0; }
.app-card .app-phone { width: 220px; margin: 0 auto; }
.app-card figcaption {
  color: rgba(247, 243, 235, 0.75);
  font-size: 15px;
  line-height: 1.55;
  text-align: center;
  max-width: 21em;
  margin: 22px auto 0;
}
.app-cta {
  display: flex;
  align-items: center;
  gap: 18px;
  margin-top: 48px;
  padding-top: 32px;
  border-top: 1px solid rgba(214, 183, 123, 0.2);
}
.app-cta p { margin: 0; color: rgba(247, 243, 235, 0.6); font-size: 14px; }

/* Sections */
.section { padding: 80px 0; }
.section-dark { background: var(--charcoal); color: var(--porcelain); }
.section-green { background: var(--green); color: var(--porcelain); }

/* Brass ring motif from the share card, echoed on dark surfaces */
.section-dark, .section-green, .page-head { position: relative; overflow: hidden; }
.section-dark::before, .section-green::before, .page-head::before {
  content: "";
  position: absolute;
  right: -190px;
  top: -340px;
  width: 820px;
  height: 820px;
  border-radius: 50%;
  background: repeating-radial-gradient(circle,
    transparent 0 104px,
    rgba(214, 183, 123, 0.16) 104px 105.5px);
  pointer-events: none;
}
.section-dark > .wrap, .section-green > .wrap, .page-head > .wrap { position: relative; }
.section-porcelain { background: var(--porcelain); }
.section h2 { font-size: clamp(30px, 4vw, 44px); margin-bottom: 20px; }
.section .sub { color: var(--stone); max-width: 44em; margin-bottom: 44px; font-size: 17px; }
.section-dark .sub, .section-green .sub { color: rgba(247, 243, 235, 0.7); }

.grid-3 { display: grid; grid-template-columns: repeat(3, 1fr); gap: 28px; }
.grid-2 { display: grid; grid-template-columns: repeat(2, 1fr); gap: 28px; }
.grid-detail { grid-template-columns: 1.4fr 1fr; align-items: start; }
.detail-side { position: sticky; top: calc(var(--pw-header-height, 73px) + 20px); }
@media (max-width: 880px) {
  .detail-side { position: static; }
}

.card {
  background: var(--porcelain);
  border: 1px solid rgba(17, 19, 18, 0.1);
  border-radius: 4px;
  padding: 32px 28px;
}
.section-dark .card, .section-green .card {
  background: rgba(247, 243, 235, 0.05);
  border-color: rgba(214, 183, 123, 0.3);
  color: var(--porcelain);
}
.card h3, .card .card-h { font-size: 22px; margin-bottom: 12px; }
.card p { font-size: 15px; color: var(--stone); }
.section-dark .card p, .section-green .card p { color: rgba(247, 243, 235, 0.7); }
.card .step-no {
  font-family: var(--serif);
  font-size: 15px;
  color: var(--brass);
  display: block;
  margin-bottom: 14px;
}

/* Space cards */
.space-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 28px; }
.space-card {
  background: var(--porcelain);
  border: 1px solid rgba(17, 19, 18, 0.12);
  border-radius: 4px;
  overflow: hidden;
  text-decoration: none;
  display: flex;
  flex-direction: column;
  transition: border-color 0.15s ease, box-shadow 0.15s ease;
}
.space-card:hover { border-color: var(--brass); }
.space-card .photo {
  aspect-ratio: 4 / 2.6;
  background: var(--green);
  display: flex;
  align-items: center;
  justify-content: center;
  position: relative;
  overflow: hidden;
}
/* Pinned absolutely so the frame's ratio is the law: aspect-ratio is
   only a preferred size, and an in-flow portrait photo's intrinsic
   height would win and stretch the whole card (and its grid row). */
.space-card .photo img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.space-card .photo svg { width: 64px; opacity: 0.65; }
.space-card .body { padding: 20px 22px 22px; }
.space-card h3 { font-size: 19px; margin-bottom: 6px; }
.space-card .meta { font-size: 13.5px; color: var(--stone); margin-bottom: 12px; }
.space-card .price { font-family: var(--serif); font-size: 22px; }
.space-card .price span { font-family: var(--sans); font-size: 13px; color: var(--stone); }

.pill {
  display: inline-block;
  font-size: 11px;
  letter-spacing: 0.02em;
  font-weight: 700;
  border-radius: 3px;
  padding: 3px 9px;
  vertical-align: middle;
}
.pill-green { background: var(--green); color: var(--porcelain); }
.pill-brass { background: var(--brass); color: var(--charcoal); }
.pill-stone { background: rgba(122, 125, 117, 0.18); color: var(--stone); }
.pill-terracotta { background: var(--terracotta); color: var(--porcelain); }
.pill-moss { background: var(--moss); color: var(--porcelain); }

/* Filter drawer: icon-only sliders button in the search row, JustPark-style,
   with a count badge when filters are active */
.filter-btn {
  position: relative;
  background: transparent;
  border: 1px solid var(--brass);
  color: var(--brass);
  border-radius: 3px;
  padding: 0 13px;
  cursor: pointer;
  display: flex;
  align-items: center;
  flex: 0 0 auto;
}
.filter-btn:hover, .filter-btn[aria-expanded="true"] { background: var(--brass); color: var(--charcoal); }
.filter-btn svg { width: 16px; height: 16px; }
.filter-badge {
  position: absolute;
  top: -7px;
  right: -7px;
  background: var(--brass);
  color: var(--charcoal);
  border-radius: 50%;
  font-size: 10px;
  font-weight: 700;
  width: 16px;
  height: 16px;
  line-height: 16px;
  text-align: center;
}
.filter-panel { margin-top: 10px; color: var(--porcelain); }
.filter-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 7px 12px;
  font-size: 13px;
}
.filter-grid label { display: flex; gap: 7px; align-items: center; cursor: pointer; }
.filter-grid input { accent-color: var(--brass); }
.filter-row2 { display: flex; gap: 8px; margin-top: 12px; }
.filter-row2 select, .filter-row2 input {
  flex: 1;
  min-width: 0;
  padding: 8px;
  border: none;
  border-radius: 3px;
  font-size: 13px;
  font-family: var(--sans);
}
.filter-row2 select {
  appearance: none;
  -webkit-appearance: none;
  padding-right: 28px;
  background-color: var(--porcelain);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='7'%3E%3Cpath d='M0 0h10L5 7z' fill='%23D6B77B'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 10px center;
  background-size: 10px 7px;
}

/* Sidebar ad panel: clicking a map pin swaps the result list for the full
   ad, YourParkingSpace-style. Close returns to the list. */
.space-panel { flex: 1; overflow-y: auto; padding: 16px; background: var(--parchment); }
.space-panel .sp-head { display: flex; align-items: flex-start; gap: 10px; }
.space-panel .sp-head h3 { flex: 1; font-family: var(--serif); font-size: 21px; margin: 0; }
.space-panel .sp-close {
  border: 1px solid rgba(17, 19, 18, 0.25);
  background: var(--porcelain);
  color: var(--charcoal);
  border-radius: 3px;
  font-size: 16px;
  line-height: 1;
  padding: 5px 9px;
  cursor: pointer;
}
.space-panel .sp-close:hover { background: var(--charcoal); color: var(--brass); }
.space-panel .sp-meta { color: var(--stone); font-size: 13.5px; margin-top: 4px; }
/* Sidebar photos: one carousel, every photo cropped to the same shape */
.space-panel .sp-carousel {
  position: relative;
  margin-top: 12px;
  border-radius: 4px;
  overflow: hidden;
  background: var(--charcoal);
}
.space-panel .sp-track { display: flex; transition: transform 0.28s ease; }
.space-panel .sp-track a { flex: 0 0 100%; display: block; }
.space-panel .sp-track img {
  width: 100%;
  aspect-ratio: 4 / 3;
  object-fit: cover;
  display: block;
}
.space-panel .sp-arrow {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  width: 30px;
  height: 30px;
  border: none;
  border-radius: 50%;
  background: rgba(17, 19, 18, 0.55);
  color: var(--porcelain);
  font-size: 18px;
  line-height: 1;
  cursor: pointer;
}
.space-panel .sp-arrow:hover { background: var(--green); }
.space-panel .sp-prev { left: 8px; }
.space-panel .sp-next { right: 8px; }
.space-panel .sp-dots {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 8px;
  display: flex;
  justify-content: center;
  gap: 6px;
}
.space-panel .sp-dot {
  width: 7px;
  height: 7px;
  padding: 0;
  border: none;
  border-radius: 50%;
  background: rgba(247, 243, 235, 0.5);
  cursor: pointer;
}
.space-panel .sp-dot.active { background: var(--brass); }
.space-panel .sp-price { font-family: var(--serif); font-size: 30px; margin-top: 14px; }
.space-panel .sp-price span { font-family: var(--sans); font-size: 13px; color: var(--stone); }
.space-panel .sp-short { color: var(--stone); font-size: 13.5px; margin-top: 2px; }
.space-panel .sp-pills { margin-top: 10px; display: flex; gap: 6px; flex-wrap: wrap; }
.space-panel .sp-desc { font-size: 14.5px; margin-top: 12px; }
.space-panel .sp-features { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 12px; }
.space-panel .sp-features span {
  background: var(--green);
  color: var(--porcelain);
  font-size: 12px;
  font-weight: 600;
  border-radius: 3px;
  padding: 4px 9px;
}
.space-panel .btn { width: 100%; text-align: center; box-sizing: border-box; }

/* Instant book: a small bolt marks hosts who accept bookings automatically.
   EV charging: a plug, matching the symbol drivers know from ParkLet. */
.bolt-icon, .plug-icon { width: 11px; height: 11px; vertical-align: -1px; fill: currentColor; margin-right: 3px; }
/* The walking man wears brass so the walk time stands out of the
   stone-coloured meta line. */
/* Negative vertical margins cancel the icon's extra height so a 15px
   man never inflates the 12px meta line's line box (the margin-bottom
   also plants his feet 3px below the baseline, like vertical-align). */
.walk-icon { width: 17px; height: 17px; fill: var(--brass); margin: -6px 1px -3px; }
.pill .bolt-icon, .pill .plug-icon { margin-right: 4px; }
.map-pill .bolt-icon, .map-pill .plug-icon { width: 10px; height: 10px; margin-left: 4px; margin-right: 0; vertical-align: -1px; }
.feature-tile .plug-icon { width: 13px; height: 13px; vertical-align: -2px; margin-right: 5px; }

/* Forms */
.form-card {
  background: var(--porcelain);
  border: 1px solid rgba(17, 19, 18, 0.12);
  border-radius: 4px;
  padding: 40px;
  max-width: 560px;
}
.form-wide { max-width: 760px; }
.form-row { margin-bottom: 22px; }
.form-row label {
  display: block;
  font-size: 12px;
  letter-spacing: 0.03em;
  font-weight: 700;
  color: var(--stone);
  margin-bottom: 7px;
}
.form-row input[type=text], .form-row input[type=email],
.form-row input[type=password], .form-row input[type=number],
.form-row input[type=date], .form-row input[type=datetime-local],
.form-row input[type=tel],
.form-row select, .form-row textarea {
  width: 100%;
  font-family: var(--sans);
  font-size: 16px;
  padding: 12px 14px;
  border: 1px solid rgba(17, 19, 18, 0.25);
  border-radius: 3px;
  background: #fff;
  color: var(--charcoal);
}
/* iOS Safari sizes date and datetime inputs by their UA intrinsics and
   ignores width: 100% unless appearance is reset, which is why they
   overflowed the booking card on phones. */
.form-row input[type=date], .form-row input[type=datetime-local],
.side-search-dates input[type=date],
.side-search-dates input[type=datetime-local] {
  -webkit-appearance: none;
  appearance: none;
  display: block;
  max-width: 100%;
  min-width: 0;
  min-height: 47px;
  text-align: left;
}
.form-row textarea { min-height: 110px; resize: vertical; }
.form-row input:focus, .form-row select:focus, .form-row textarea:focus {
  outline: 2px solid var(--brass);
  border-color: var(--brass);
}
.form-row .hint { font-size: 13px; color: var(--stone); margin-top: 5px; }
.form-split { display: grid; grid-template-columns: 1fr 1fr; gap: 18px; }
/* A single-line capture field (email, postcode, feed url) used in the
   strips on home, hosts, business, search, 404, and in two back-office
   forms. This was the same inline style copied onto thirteen inputs.
   The values are unchanged; they just live somewhere the phone media
   query can reach, because iOS zooms the page on any field under 16px
   and an inline style cannot be overridden. */
.inline-field {
  padding: 12px;
  border: 1px solid rgba(17, 19, 18, 0.25);
  border-radius: 3px;
  font-size: 15px;
}
.inline-field-tight { padding: 11px; font-size: 14px; }
.inline-field-sm { padding: 6px 8px; font-size: 13px; }
.inline-field-dark {
  padding: 14px;
  border: 1px solid rgba(214, 183, 123, 0.5);
  border-radius: 3px;
  background: rgba(247, 243, 235, 0.06);
  color: var(--porcelain);
  font-size: 15px;
}

.checkbox-row { display: flex; gap: 24px; flex-wrap: wrap; font-size: 15px; }
.checkbox-row label { display: flex; align-items: center; gap: 8px; }

/* Flash messages */
.flash-stack { margin: 24px auto 0; }
.flash {
  background: var(--green);
  color: var(--porcelain);
  border-left: 4px solid var(--brass);
  border-radius: 3px;
  padding: 14px 18px;
  margin-bottom: 10px;
  font-size: 15px;
}

/* Email capture on pages that already have something to show: quiet
   enough not to compete with the results, present enough to be seen. */
.watch-strip {
  display: flex;
  gap: 18px;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  margin-top: 24px;
  padding: 16px 18px;
  background: rgba(17, 19, 18, 0.04);
  border-left: 3px solid var(--brass);
  border-radius: 3px;
}
.watch-strip .watch-title { font-weight: 600; font-size: 15px; }
.watch-strip form { display: flex; gap: 8px; flex-wrap: wrap; }
.watch-strip input[type="email"] {
  padding: 10px 12px;
  border: 1px solid rgba(17, 19, 18, 0.25);
  border-radius: 3px;
  font-size: 14px;
  min-width: 190px;
}
@media (max-width: 640px) {
  .watch-strip form, .watch-strip input[type="email"] { width: 100%; }
}

/* Marks a listing that sells a monthly pass only, on the row it belongs
   to. A pill rather than a paragraph: the explanation is said once
   under the table instead of repeated for every listing. */
.rate-pill {
  display: inline-block;
  margin-top: 6px;
  text-decoration: none;
}
.rate-pill:hover { background: var(--brass); color: var(--charcoal); }

/* An inline warning that reads like the flash banner but sits in the
   page flow, for a caution about what is already on screen. */
.notice {
  background: var(--porcelain);
  border-left: 4px solid var(--brass);
  border-radius: 3px;
  padding: 14px 18px;
  font-size: 15px;
}
.notice-warn { border-left-color: var(--terracotta); background: rgba(180, 92, 62, 0.08); }

/* Tables */
.data-table { width: 100%; border-collapse: collapse; background: var(--porcelain); font-size: 14.5px; }
.data-table th {
  text-align: left;
  font-size: 11.5px;
  letter-spacing: 0.03em;
  color: var(--stone);
  border-bottom: 2px solid var(--charcoal);
  padding: 10px 12px;
}
.data-table td { padding: 12px; border-bottom: 1px solid rgba(17, 19, 18, 0.1); vertical-align: top; }
.table-scroll { overflow-x: auto; border: 1px solid rgba(17, 19, 18, 0.12); border-radius: 4px; }

/* Page headers for inner pages */
.page-head { background: var(--charcoal); color: var(--porcelain); padding: 64px 0 56px; }
.page-head h1 { font-size: clamp(34px, 5vw, 56px); }
.page-head p { color: rgba(247, 243, 235, 0.7); margin-top: 14px; max-width: 40em; font-size: 17px; }

/* Prose (faq, terms) */
.prose { max-width: 720px; }
.prose h2 { font-size: 26px; margin: 36px 0 12px; }
.prose h3 { font-size: 20px; margin: 26px 0 10px; }
.prose p, .prose li { color: #3a3d3b; margin-bottom: 12px; font-size: 16px; }
.prose ul { padding-left: 22px; }

/* Suggestions dropdown */
.suggest-box {
  position: absolute;
  top: 100%;
  left: 0;
  right: 0;
  background: var(--porcelain);
  border: 1px solid var(--brass);
  border-top: none;
  border-radius: 0 0 4px 4px;
  z-index: 1200;
  box-shadow: 0 8px 20px rgba(17, 19, 18, 0.18);
  max-height: 320px;
  overflow-y: auto;
}
.suggest-item {
  padding: 11px 16px;
  font-family: var(--serif);
  font-size: 17px;
  color: var(--charcoal);
  cursor: pointer;
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 14px;
}
.suggest-item:hover, .suggest-item.active { background: var(--parchment); color: var(--green); }
.suggest-kind {
  font-family: var(--sans);
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--stone);
  white-space: nowrap;
}

/* Search layout, ParkLet style: search and listings in a sidebar, the
   map takes everything else. No footer on this page. */
.search-shell { padding: 0; }
.search-layout {
  display: grid;
  grid-template-columns: 380px minmax(0, 1fr);
  gap: 0;
  align-items: stretch;
  height: calc(100vh - var(--pw-header-height, 73px));
  min-height: 560px;
}
.search-sidebar {
  display: flex;
  flex-direction: column;
  min-height: 0;
  background: var(--parchment);
  border-right: 1px solid rgba(17, 19, 18, 0.15);
}
.side-search {
  padding: 14px 14px 12px;
  background: var(--charcoal);
}
.side-search-dest { position: relative; display: flex; gap: 8px; }
.side-search-dest input {
  flex: 1;
  min-width: 0;
  font-family: var(--serif);
  font-size: 17px;
  padding: 11px 14px;
  border: 1px solid var(--brass);
  border-radius: 3px;
  background: var(--porcelain);
  color: var(--charcoal);
  outline: none;
  box-sizing: border-box;
}
.side-search-go { flex: 0 0 auto; padding: 0 20px; font-size: 14px; }
/* Keyboard focus must be visible everywhere the search UI removed the
   default outline (WCAG 2.4.7). Brass reads on both the dark sidebar
   and the porcelain hero panel. */
.search-panel input:focus-visible, .search-panel select:focus-visible,
.side-search-dest input:focus-visible,
.side-search-dates input:focus-visible,
.side-search-dates select:focus-visible,
.side-search-row select:focus-visible {
  outline: 2px solid var(--brass);
  outline-offset: 1px;
}
.side-search-dates { margin-top: 10px; }
.side-search-dates span { display: flex; gap: 8px; flex-wrap: wrap; }
.side-search-dates span[hidden] { display: none; }
.side-search-dates input[type=date],
.side-search-dates input[type=datetime-local] {
  flex: 1 1 120px;
  min-width: 0;
  font-family: var(--sans);
  font-size: 14px;
  padding: 9px 10px;
  border: 1px solid rgba(214, 183, 123, 0.5);
  border-radius: 3px;
  background-color: rgba(247, 243, 235, 0.08);
  color: var(--porcelain);
  outline: none;
  color-scheme: dark;
}
.side-search-dates select { flex: 1 1 90px; }
.side-search-row { display: flex; gap: 8px; margin-top: 10px; }
.side-search-row select, .side-search-dates select {
  flex: 1;
  font-family: var(--sans);
  font-size: 13px;
  padding: 9px 30px 9px 10px;
  border: 1px solid rgba(214, 183, 123, 0.5);
  border-radius: 3px;
  background-color: rgba(247, 243, 235, 0.08);
  color: var(--porcelain);
  outline: none;
  appearance: none;
  -webkit-appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='7'%3E%3Cpath d='M0 0h10L5 7z' fill='%23D6B77B'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 12px center;
  background-size: 10px 7px;
}
.side-search-row select option, .side-search-dates select option { color: var(--charcoal); }
.search-list {
  display: flex;
  flex-direction: column;
  gap: 14px;
  overflow-y: auto;
  padding: 14px;
  min-height: 0;
}
.search-list > * { flex-shrink: 0; }
.search-count {
  font-size: 12.5px;
  color: var(--stone);
  margin: 0 0 2px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Sidebar cards: photo on the left like ParkLet */
/* Every result tile is exactly the same height, so the list scans as a
   column and as many fit on screen as possible. The title reserves two
   lines whether it needs them or not, which is what makes the heights
   identical rather than merely similar. */
.space-row { flex-direction: row; align-items: stretch; height: 136px; }
/* 136px: the content needs 133 with a two-line title, and the few
   spare pixels absorb the metric differences between the system
   fonts this stack resolves to on other platforms. */
/* Block layout, deliberately: the pills are inline chips, and making
   the body a flex column stretched them to full width, which overflowed
   the fixed height and pushed the meta line out of the card. */
.space-row .body { overflow: hidden; }
.space-row h3 {
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  min-height: 2.5em;
}
.space-row .photo {
  width: 112px;
  flex: 0 0 112px;
  aspect-ratio: auto;
}
.space-row .body { padding: 9px 12px; min-width: 0; }
.space-row h3 { font-size: 14.5px; line-height: 1.22; margin-bottom: 2px; }
/* Type, distance and walk time stay on one row whatever the values.
   The outcode is not repeated here: the title already carries it. The
   longest real line (Off-street bay, 12.4 mi, a two-hour walk) needs
   196px of the 213 available, and the ellipsis is a backstop that real
   data never reaches. */
.space-row .meta {
  font-size: 12px;
  margin-bottom: 3px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.space-row .meta .walk-icon { width: 13px; height: 13px; margin: -5px 1px -3px 2px; }
.space-row .price { font-size: 15.5px; margin-bottom: 2px; }
.space-row .pill { font-size: 9.5px; padding: 2px 7px; }
/* Hovering a map pin rolls its card to the top with a thick brass ring */
.space-card.pin-hover {
  border-color: var(--brass);
  box-shadow: 0 0 0 2.5px var(--brass);
}
.search-map { position: relative; }
#map { height: 100%; width: 100%; border: none; }
.space-card .photo img.logo-ph {
  position: static;
  width: 46px;
  height: 46px;
  object-fit: contain;
  opacity: 0.9;
}

/* Map style switcher, like the Prime Parking zones map */
.map-style-ctl {
  position: absolute;
  top: 12px;
  left: 12px;
  z-index: 6;
  display: flex;
  background: var(--porcelain);
  border: 1px solid rgba(17, 19, 18, 0.25);
  border-radius: 4px;
  overflow: hidden;
  box-shadow: 0 2px 8px rgba(17, 19, 18, 0.2);
}
.map-style-ctl button {
  border: none;
  background: transparent;
  font-family: var(--sans);
  font-size: 12px;
  font-weight: 600;
  color: var(--charcoal);
  padding: 7px 12px;
  cursor: pointer;
  border-right: 1px solid rgba(17, 19, 18, 0.12);
}
.map-style-ctl button:last-child { border-right: none; }
.map-style-ctl button.active { background: var(--charcoal); color: var(--brass); }

.map-area-btn[hidden] { display: none; }
.map-area-btn {
  position: absolute;
  top: 12px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 7;
  box-shadow: 0 2px 8px rgba(17, 19, 18, 0.3);
}

/* Price pill markers: compact, with a pointer tail on the exact spot */
.map-pill {
  position: relative;
  background: var(--charcoal);
  color: var(--brass);
  border: 1px solid var(--brass);
  border-radius: 4px;
  padding: 2px 7px;
  margin-bottom: 6px;
  font-family: var(--sans);
  font-size: 11.5px;
  font-weight: 700;
  line-height: 1.3;
  /* Both lines centred on each other: the price reads as the label and
     the walk as its footnote, rather than two things left-aligned in a
     box. No rule between them; the size difference does that work. */
  text-align: center;
  white-space: nowrap;
  cursor: pointer;
  box-shadow: 0 2px 6px rgba(17, 19, 18, 0.35);
}
.map-pill::before {
  content: "";
  position: absolute;
  left: 50%;
  bottom: -7.5px;
  transform: translateX(-50%);
  border-left: 7.5px solid transparent;
  border-right: 7.5px solid transparent;
  border-top: 7.5px solid var(--brass);
}
.map-pill::after {
  content: "";
  position: absolute;
  left: 50%;
  bottom: -5.5px;
  transform: translateX(-50%);
  border-left: 6px solid transparent;
  border-right: 6px solid transparent;
  border-top: 6px solid var(--charcoal);
}
/* Overlapping pins: whichever one the cursor is on comes to the front,
   so a price hidden behind its neighbour can always be read. */
.map-pill:hover { background: var(--green); z-index: 4; }
.map-pill:hover::after { border-top-color: var(--green); }
/* Sold out sits under everything bookable. Where two spaces are yards
   apart the pins overlap, and a driver reading the map should never
   have a space they cannot book hiding one they can. Hover still lifts
   whichever pin is under the cursor, so a covered one is reachable. */
/* Pins sit under every control. They are content: the zoom, compass,
   style switcher and Search this area are how you work the map, and a
   price label covering one is a control you cannot press. The whole
   stack, low to high: sold out pins, live pins, a hovered pin, then the
   controls above all of them. */
/* The pin you are looking at, with the walk to it written underneath:
   a figure, the minutes and the miles. Brass on charcoal so it reads as
   one label with the price above it. */
.map-pill.is-chosen { background: var(--brass); color: var(--charcoal); z-index: 5; }
.map-pill.is-chosen::after { border-top-color: var(--brass); }
.map-pill-walk {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 4px;
  margin: 0;
  font-size: 9.5px;
  font-weight: 700;
  letter-spacing: 0.01em;
  white-space: nowrap;
  opacity: 0.85;
}
/* The figure is drawn larger than his line and allowed to rise out of
   it: there is clear air above him now the price sits in the middle, so
   he can be a proper little walking man rather than a 9px smudge. The
   negative margins keep him from making the row, and so the pin, taller.
   He is Henry's own image used as a mask, so the shape is exactly his
   and the colour is still ours: currentColor fills it, and it inverts
   with the pin from brass on charcoal to charcoal on brass. */
.map-pill-walk .walk-man {
  display: block;
  width: 12px;
  height: 17px;
  flex: none;
  margin: -7px 1px -2px 0;
  background-color: currentColor;
  -webkit-mask: url("/static/img/walk.png") no-repeat center / contain;
  mask: url("/static/img/walk.png") no-repeat center / contain;
}
.map-pill { z-index: 3; }
.map-pill-taken { background: var(--stone); z-index: 1; }
.mapboxgl-control-container .mapboxgl-ctrl-top-left,
.mapboxgl-control-container .mapboxgl-ctrl-top-right,
.mapboxgl-control-container .mapboxgl-ctrl-bottom-left,
.mapboxgl-control-container .mapboxgl-ctrl-bottom-right { z-index: 8; }
.map-pill-taken::after { border-top-color: var(--stone); }
/* Searched-place marker: the boot sways above the pulsing target point
   at rest and hangs from the cursor with pendulum physics while dragged.
   Mapbox positions the wrapper with its own transform, so all animation
   lives on the inner elements. Hang point is the top of the shaft
   (27.3px 4.8px), under the brass pull-loop. */
/* Price pins stay above the resting boot so coincident locations remain
   tappable. The visible shaft remains draggable; a grabbed boot is lifted. */
/* The map already owns the grab cursor for panning, so the boot gets its
   own: a brass arcade claw, open over the boot and closed while dragging.
   Dark outline keeps it readable on both light and dark map styles.
   Falls back to grab if a browser refuses SVG cursors. */
.map-origin {
  position: relative;
  /* Resting boot 0, sold out pins 1, live pins 3, hover 4, selection 5,
     style switcher 6, area search 7 and map controls 8. A drag lifts the
     boot to 60 only until it lands. This leaves coincident price pins
     accessible to a finger without shrinking the boot's grab target. */
  z-index: 0;
  width: 26px;
  height: 36px;
  background: none;
  border: none;
  cursor: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACQAAAAkCAYAAADhAJiYAAAFEElEQVR4nOxYa0wUVxQ+d2ZZ2QX2CctrKegCliobsSqYCKUGTLCQhqZpEx+N9oe2iVKTPtKYtEFNbf1HUhpoY2ya/mibBrXQxoIvcAmlGh5FhUWCiBREYB/Asrss7E7PnSWblNc+pk38wZdM9p6zc+d+997vnHNnRCAQCrWilHDkTdrmCPeT1WS9BAJAQAAUKsVhQpgLcdGRvD06YQOO87xtNVu/hRDBgBAQ8mpyggJqKg7yF21THwiAMEIAcm2s3Gckxsp4HwiACJ4xrBHyB6EagpREJcY78BffFggWQgTHAWEtRaf3F2+V88kDrx2bk0CtkDLXW4wVECJCzkPdv598DzNhhdXugtb+Md63M1UDcokYCAfHM/Z+VgkhICRCg79+rJwmzCg2xcUV18Dumuf9keEiqC0rwN3jHOFkXVza3vIpCBKhaIhUXm47yzBE3Dlk8pGhsDnn4d6wBViGkVRdbDkFIUw4KEIymSxNqVK19D42vUPtMGZpdyTK//YNjp+g99I+EAQCJqRUKvVsmKhDGy/Peat4K+/LTFLB+phI3z06TRRsXoi0AyVZkBAblYN92mnfQMcJaEkVCkUK7sOfOq1S83X5ayANF3tDfaG34cFTELMMZOti/tXPhoI/Ul4Dj0asY7McbHOYzUP+xvIb9khGASxpjlFGJFV9WgrySAnvHxgxwxVDL6SnRMMGjQy0qgiYRT39XN8FkVIxKGUSEIexkPvierjR2h/hcs4VOSWS78HhmBVESCKVXIiQivOqPimF+Bi+eELXg1F49/QlaO183NPRPby/JD/jOkZWzfEzv1TXNhlzfmsyqrdnakGjioQITAM5W5Kg3tAXzcy7E5wOx+XVxlt1y2Rq2XYWRLdPHsmHV/IyeN/Dv81w9NRFmHHM3bGazHnoci7qFqFQKw1R0nVZ3+D2Jid4NVXX2ANfnG8Ezu3JslqtnSuNuZqoCcOx51OT1T4yoyYblJ2tBbvddR/cnj3LkKGYcbvmC1E/vWWf18K4xcY7i196HlKQHGGY6lXGXJmQ9zRI9B8dzvP5yisbwDJpH5pzze3GWVpX6js9PW2aJc7dExb7yJnqG97ZEQIfHMqle5KNsjwYHKFoiMKe517eoYNNqXG8y9A2AHf7ntLo2mez2cbAD+wT9hEP5z7Udn8YWjoHeV/WC4ko8hQsgsw5NKUBE5J7VG9ghEQf27eTtz0eDr764Q9aUK9aLJZmCBCT5smrHMfdqv6xlX8GxYkDu0DEknh8OXg9YEIMcAXZ+iSIi47ibSrIodFJLJrc+xAkPMT9YT8GwpVmI2/HxUTBtk1abJHC5cdeHkX69HifUdfYTQtmO67OXQgSU6ap27i09+pu9vh8+o1UBmQPBEIIBbcFFSjXb/QSmnG4wDgwTvNDA4QInExDNx5RZhcKsT4tnj5PgyUl0y8hjmEKaIbN2KDh7b96n1DtYP7ghBCqd6OGuvqe8HaGTkN1hMeppdu2hBAh3K50zD0i1vtXp3GE/sxglN+CEIHiNqC4XR3dXkLh68JA95waB+Ny/RPiSLh5ygGuheVtbn9EZ3gNm24IHQ7co/qmOw95gz7bOuWkJ8uwJeMvdsiVyqN4pqnGYgosLiv/euz20ER4EwRArpIXMoRtSMAjimvODZg0l33tXraWobDz8aR1zHuHpw4/IHwH/wFo9sdNKcHmPKaQLzFqDYvvEfSx4f/A2purP6wR8odnjtA/AAAA///EEAXqAAAABklEQVQDAHpR1Nsry2RWAAAAAElFTkSuQmCC") 18 12, grab;
}
.map-origin.dragging { z-index: 60; }
.map-origin:active,
.map-origin.dragging {
  cursor: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACQAAAAkCAYAAADhAJiYAAADZElEQVR4nOyXX0hTURzHf+fO3NK53c0/K//g3/zH+sMeMsOeKjARKkR6iIhaT0H10kP0FEFQb4OCXszopYgQs39ElEmCSkYEpaapICbb0u3ezbHNNXc650yuRg/r3Kvgwz7j7Jzf7+zufPnd3/ndczNAI2KueBxhdIKOMcKPZZ/cDRpAoAHRKp5BSOjclmdktmchBBgnzsp++T6oRAAtIHS0tFCELtcp1uiY+kAD2gQBmIttZsUospmYDzSQAZuMtKBUbDpBWpMayoospAABa2ysER2oBGNAOunI9ZOtDjOrZqTttZdArpglvBv47gKVqC6Mo6+vXiKl2SWHYzA09Yv5GqsKwLw1ExCGC3UtN+6AClQJmnlxxRISBDeJkr7V9RbCsTjzGw0Z8OziIfqvYT1kbt/Rci0InKjKobCga0II6b/M+hQxlFA0Dt/mJBAQyoqjWCOoQJUgDAmWe1uEfy8XhGTQEWA9qECVoLsPB3y031lihfJ8o+KvLMgB+8pOu/1oYB5UoGqXTcwGL+t0qGFPbSEcc5QSISZothfB+YN1bP5e1zA86PkciEaib4ATNRHKQgJyeslRg4JJZh+otkFDZT4b049nYZHcMuEc/S1wwi2IHMicdKH25l3MjkRjcKujD26StrQUJ0IQtB220yQyWSyW08CJigihNjupNxXFVma9/DAOPe9H4XnfGLzqH2e+2ooCqKsgERNQG3DCK4jsIdTQ5ChXHL1Dk7TrJ/drsPfjlOJvcpTRIrefdw2uH4uiuJt0hpryPGbHlxMwwqo0eprA0DMy6WU+SnVZPu22Gi2Weo4l+ASRYriP9vWVNmaP/PDAMlGCMB6GRGI49nsZxqaTj5GasqRoHUJcBZJLEHmrqMo2ZIIxK1nzpklVJjsrIUnSp0AgMEh9M3N+NpcrZoM+U0fuMa7kWII3hwSzKWe1AMvBMI2ahwwjtJEtPy8Fo8q8KdtAO64zNm9Sm81Gg2JIgSh9jsir00iWgpE1gvR0nksQ74nxb0GLYfKN1wgC2b9GUI6RRXNDIxSacUuKQXcVSWmv4sDw8+uEWzHd80E6vwQccJ2HzFarkxSiDltu8oHq9bE3VSd5U+38n/l1F7SyaDu5iDQcTwDqDvj9T3jm113QRpN+L0tFWlAq0oJS8QcAAP//2LiErgAAAAZJREFUAwDqLyVGS/3/rQAAAABJRU5ErkJggg==") 18 13, grabbing;
}

/* The boot answers the cursor: it lifts toward the claw, the pull loop
   brightens, and a tag says what to do. Hover only, so touch is unaffected. */
.map-origin .grab-tag {
  position: absolute;
  left: 50%;
  bottom: 46px;
  transform: translateX(-50%) translateY(4px);
  white-space: nowrap;
  background: var(--charcoal);
  color: var(--brass);
  border: 1px solid var(--brass);
  border-radius: 3px;
  font-family: var(--sans);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.04em;
  padding: 4px 9px;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.16s ease, transform 0.16s ease;
}
@media (hover: hover) {
  .map-origin:hover .grab-tag { opacity: 1; transform: translateX(-50%) translateY(0); }
  /* The kick and its ground pulses share one heartbeat, so a hover
     must pause BOTH timelines: pausing only the boot let every hover
     (including the one you are in the moment you drop it) slide the
     kick out of phase with the pulses. */
  .map-origin:hover .origin-boot,
  .map-origin:hover .origin-pulse { animation-play-state: paused; }
  /* visibility, not opacity: opacity belongs to the paused keyframes,
     and a frozen mid-flight ring would hang in the air. The lifted
     boot is not kicking, so no pulse should show. */
  .map-origin:hover .origin-pulse { visibility: hidden; }
  .map-origin:hover .origin-boot svg { filter: drop-shadow(0 7px 6px rgba(17, 19, 18, 0.4)); }
  .map-origin:hover .origin-boot { transform: rotate(-23deg) translateY(-5px); }
}
.map-origin.dragging .grab-tag { opacity: 0; }
/* No hover, no reveal: on a touch screen the tag never appeared at
   all, though the phone rules further down size it on the belief that
   it is the only thing telling a thumb the boot can be dragged. Where
   hover does not exist the tag simply stays up, and still hides while
   a drag is under way. */
@media (hover: none) {
  .map-origin:not(.dragging) .grab-tag {
    opacity: 1;
    transform: translateX(-50%) translateY(0);
  }
}
/* Generous invisible hit pad: the boot, target and pulses all live
   outside the wrapper's own box, so grabs anywhere near them must land
   on the marker rather than the map */
.map-origin .origin-hit {
  position: absolute;
  left: -12px;
  top: -30px;
  width: 50px;
  height: 74px;
}
.map-origin .origin-boot {
  display: block;
  position: absolute;
  left: 50%;
  bottom: 1px;
  width: 48px;
  height: 48px;
  margin-left: -24px;
  transform-origin: 34.5px 6px;
  transform: rotate(-23deg);
  filter: drop-shadow(0 4px 4px rgba(17, 19, 18, 0.32));
  pointer-events: none;
  animation: boot-kick 1.6s ease-in-out infinite;
}
.map-origin .origin-boot svg { display: block; }
.map-origin.dragging .origin-boot {
  animation: none;
  transform: none;
  left: 0;
  bottom: auto;
  top: 0;
  margin-left: 0;
  filter: drop-shadow(0 14px 9px rgba(17, 19, 18, 0.3));
}
/* Heartbeat: kick-kick-pause. At rest the toe sits on the bullseye;
   each kick presses through it */
@keyframes boot-kick {
  0% { transform: rotate(-23deg); }
  10% { transform: rotate(-31deg); }
  20% { transform: rotate(-23deg); }
  30% { transform: rotate(-31deg); }
  40% { transform: rotate(-23deg); }
  100% { transform: rotate(-23deg); }
}
.origin-pulse {
  position: absolute;
  left: 50%;
  bottom: -5px;
  width: 22px;
  height: 10px;
  margin-left: -11px;
  border: 1px solid var(--brass);
  border-radius: 50%;
  opacity: 0;
  transform: scale(1);
  pointer-events: none;
}
/* Pulses fire as each kick lands: 10% and 30% of the 1.6s heartbeat,
   spreading wide before they fade */
.origin-pulse-a { animation: origin-pulse-a 1.6s ease-out infinite; }
.origin-pulse-b { animation: origin-pulse-b 1.6s ease-out infinite; }
@keyframes origin-pulse-a {
  0%, 9% { transform: scale(1); opacity: 0; }
  10% { transform: scale(1); opacity: 0.8; }
  33% { opacity: 0.45; }
  52% { transform: scale(4.4); opacity: 0; }
  100% { transform: scale(4.4); opacity: 0; }
}
@keyframes origin-pulse-b {
  0%, 29% { transform: scale(1); opacity: 0; }
  30% { transform: scale(1); opacity: 0.8; }
  53% { opacity: 0.45; }
  72% { transform: scale(4.4); opacity: 0; }
  100% { transform: scale(4.4); opacity: 0; }
}

/* The target point the boot sways over, always marked; while dragging it
   shows where the boot will land */
.map-origin .drop-target {
  position: absolute;
  left: 50%;
  bottom: -5px;
  width: 22px;
  height: 11px;
  margin-left: -11px;
  border: 1px solid var(--brass);
  border-radius: 50%;
  opacity: 1;
  pointer-events: none;
}
.map-origin .drop-target::after {
  content: "";
  position: absolute;
  left: 50%;
  top: 50%;
  width: 3px;
  height: 3px;
  margin: -1.5px 0 0 -1.5px;
  border-radius: 50%;
  background: var(--brass);
}
.map-origin.dragging .origin-pulse { animation: none; opacity: 0; }
@media (prefers-reduced-motion: reduce) {
  .map-origin .origin-boot, .origin-pulse { animation: none; }
}
/* Google Maps marker on the listing minimap: the standard charcoal
   pill with its pointy tail, holding the Google G in its own colours so
   the external destination is unmistakable */
.map-pill .g-logo { display: block; padding: 1px 0; }

.mapboxgl-popup-content { font-family: var(--sans); font-size: 14px; padding: 12px 16px; }
.mapboxgl-popup-content a { color: var(--green); font-weight: 700; }

/* Stat tiles */
.stat-row { display: grid; grid-template-columns: repeat(4, 1fr); gap: 20px; }
.stat {
  background: var(--porcelain);
  border: 1px solid rgba(17, 19, 18, 0.12);
  border-radius: 4px;
  padding: 22px;
}
.stat .n { font-family: var(--serif); font-size: 34px; display: block; }

/* Calculator */
/* A charcoal panel on a charcoal section silently punched a rectangle
   through the ring motif behind it. A brass keyline makes the panel
   deliberate, and the part-transparent ground lets the rings carry on
   underneath instead of stopping at an invisible edge. */
.calc {
  background: rgba(17, 19, 18, 0.62);
  color: var(--porcelain);
  border: 1px solid rgba(214, 183, 123, 0.45);
  border-radius: 4px;
  padding: 40px;
}
.calc .result { font-family: var(--serif); font-size: 44px; color: var(--brass); }
/* appearance must be reset or iOS ignores all of this and paints its
   native white pill with our porcelain text on it, unreadably. */
.calc select {
  appearance: none;
  -webkit-appearance: none;
  width: 100%;
  font-family: var(--serif);
  font-size: 20px;
  background-color: rgba(247, 243, 235, 0.06);
  color: var(--porcelain);
  border: 1px solid rgba(214, 183, 123, 0.5);
  border-radius: 3px;
  padding: 10px 38px 10px 14px;
  outline: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='7'%3E%3Cpath d='M0 0h10L5 7z' fill='%23D6B77B'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 14px center;
  background-size: 10px 7px;
}
.calc select:focus-visible { outline: 2px solid var(--brass); outline-offset: 1px; }
.calc select option { color: var(--charcoal); }

/* Account area: vertical menu card on the left, content on the right */
.account-shell {
  display: grid;
  grid-template-columns: 264px minmax(0, 1fr);
  gap: 28px;
  max-width: 1420px;
  margin: 0 auto;
  padding: 28px 24px 64px;
  align-items: start;
}
.account-side { position: sticky; top: calc(var(--pw-header-height, 73px) + 24px); }
.account-nav-card {
  background: var(--porcelain);
  border: 1px solid rgba(17, 19, 18, 0.12);
  border-top: 3px solid var(--brass);
  border-radius: 4px;
  overflow: hidden;
}
.account-nav-head {
  padding: 16px 18px 12px;
  border-bottom: 1px solid rgba(17, 19, 18, 0.1);
}
.account-nav-title { font-family: var(--serif); font-size: 20px; }
.account-nav-user { font-size: 12.5px; color: var(--stone); margin-top: 2px; }
.account-nav a {
  display: block;
  position: relative;
  padding: 12px 18px;
  border-bottom: 1px solid rgba(17, 19, 18, 0.08);
  text-decoration: none;
  font-size: 14.5px;
  font-weight: 600;
  color: var(--charcoal);
}
.account-nav a::after {
  content: "\203A";
  position: absolute;
  right: 16px;
  color: var(--stone);
}
.account-nav a:hover { background: var(--parchment); color: var(--green); }
.account-nav a.active {
  background: var(--green);
  color: var(--porcelain);
  box-shadow: inset 3px 0 0 var(--brass);
}
.account-nav a.active::after { color: var(--brass); }
.account-nav-out { border-top: 1px solid rgba(17, 19, 18, 0.1); }
.account-nav-out button {
  display: block;
  width: 100%;
  text-align: left;
  padding: 12px 18px;
  background: transparent;
  border: none;
  font-family: var(--sans);
  font-size: 13.5px;
  font-weight: 600;
  color: var(--terracotta);
  cursor: pointer;
}
.account-nav-out button:hover { background: var(--parchment); }

/* Content column: page heads become cards, sections tighten */
.account-main { min-width: 0; }
.account-main .page-head {
  border-radius: 4px;
  padding: 40px 0 36px;
}
.account-main .page-head > .wrap,
.account-main .section > .wrap { max-width: none; }
.account-main .section { padding: 36px 0 24px; }

@media (max-width: 1024px) {
  .account-shell { display: block; padding: 18px 18px 48px; }
  .account-side { position: static; margin-bottom: 18px; }
  .account-nav-head, .account-nav-out { display: none; }
  .account-nav-card { border-top-width: 1px; }
  .account-nav { display: flex; overflow-x: auto; }
  .account-nav a {
    white-space: nowrap;
    border-bottom: none;
    border-right: 1px solid rgba(17, 19, 18, 0.08);
    font-size: 13px;
    padding: 11px 14px;
  }
  .account-nav a::after { content: none; }
}

/* Tabs */
.tab-row { display: flex; gap: 6px; border-bottom: 2px solid var(--charcoal); margin-bottom: 20px; flex-wrap: wrap; }
.tab-row a {
  text-decoration: none;
  font-size: 13px;
  letter-spacing: 0.02em;
  font-weight: 700;
  color: var(--stone);
  padding: 9px 16px;
  border-radius: 3px 3px 0 0;
}
.tab-row a.active { background: var(--charcoal); color: var(--brass); }

/* Booking calendar */
.cal-table { width: 100%; border-collapse: collapse; background: var(--porcelain); }
.cal-table td { border: 1px solid rgba(17, 19, 18, 0.1); vertical-align: top; height: 74px; width: 14.28%; padding: 6px; font-size: 13px; }
.cal-table td.other-month { background: var(--parchment); color: var(--stone); }
.cal-table td.booked { background: var(--green); color: var(--porcelain); }
.cal-table td.booked .who { font-size: 11px; color: var(--brass); display: block; margin-top: 4px; }
.cal-table td.today-cell { outline: 2px solid var(--brass); outline-offset: -2px; }

/* Message threads */
.msg-bubble { max-width: 75%; border-radius: 6px; padding: 12px 16px; margin-bottom: 10px; font-size: 15px; }
.msg-mine { background: var(--green); color: var(--porcelain); margin-left: auto; }
.msg-theirs { background: var(--porcelain); border: 1px solid rgba(17, 19, 18, 0.12); }
.msg-meta { font-size: 11.5px; color: var(--stone); margin-bottom: 4px; }
.msg-mine .msg-meta { color: rgba(247, 243, 235, 0.65); }

@media print {
  .site-header, .site-footer, .hub-nav, .no-print { display: none !important; }
  .page-head { background: none; color: var(--charcoal); padding: 0 0 12px; }
  .page-head h1 { color: var(--charcoal); }
  body { background: #fff; }
}

/* Admin dashboard */
.admin-bar { background: var(--charcoal-soft); border-bottom: 1px solid rgba(214,183,123,0.2); }
.admin-nav { display: flex; gap: 2px; flex-wrap: wrap; }
.admin-nav a {
  color: rgba(247,243,235,0.75); text-decoration: none; font-size: 13px;
  font-weight: 700; padding: 12px 15px;
}
.admin-nav a:hover { color: var(--brass); }
.admin-nav a.active { color: var(--brass); box-shadow: inset 0 -2px 0 var(--brass); }

.alert-strip { display: flex; gap: 10px; flex-wrap: wrap; margin-bottom: 22px; }
.alert-chip {
  display: inline-block; text-decoration: none; font-size: 13.5px;
  background: var(--porcelain); border: 1px solid var(--brass);
  border-left: 4px solid var(--brass);
  border-radius: 3px; padding: 9px 14px; color: var(--charcoal);
}
.alert-chip:hover { background: var(--parchment); }
.alert-chip strong { color: var(--green); }
.alert-chip.bad { border-color: var(--terracotta); border-left-color: var(--terracotta); }
.alert-chip.bad strong { color: var(--terracotta); }

.kpi-row { display: grid; grid-template-columns: repeat(4, 1fr); gap: 16px; }
.kpi {
  background: var(--porcelain); border: 1px solid rgba(17,19,18,0.12);
  border-top: 3px solid var(--green); border-radius: 4px; padding: 16px 18px;
}
.kpi .k-label { display: block; font-size: 12px; color: var(--stone); font-weight: 700; }
.kpi .k-num { display: block; font-family: var(--serif); font-size: 30px; line-height: 1.15; margin: 4px 0 2px; }
.kpi .k-sub { display: block; font-size: 12.5px; color: var(--stone); }

.bar-chart { display: flex; align-items: flex-end; gap: 6px; height: 190px; }
.bar-col { flex: 1; display: flex; flex-direction: column; justify-content: flex-end; align-items: center; height: 100%; }
.bar {
  width: 100%; min-height: 2px; background: var(--green);
  border-radius: 2px 2px 0 0; transition: background 0.15s ease;
}
.bar-col:hover .bar { background: var(--brass); }
.bar-label { font-size: 11px; color: var(--stone); margin-top: 6px; }

.activity { display: flex; flex-direction: column; max-height: 420px; overflow-y: auto; }
.activity-row {
  display: grid; grid-template-columns: 74px 1fr auto; gap: 10px; align-items: baseline;
  padding: 8px 0; border-bottom: 1px solid rgba(17,19,18,0.08);
  text-decoration: none; font-size: 13.5px;
}
.activity-row:hover { background: var(--parchment); }
.act-kind {
  font-size: 10.5px; font-weight: 700; text-transform: uppercase;
  padding: 2px 6px; border-radius: 3px; text-align: center;
  background: rgba(122,125,117,0.18); color: var(--stone);
}
.act-payment { background: var(--moss); color: var(--porcelain); }
.act-booking { background: var(--green); color: var(--porcelain); }
.act-space { background: var(--brass); color: var(--charcoal); }
.act-support { background: var(--terracotta); color: var(--porcelain); }
.act-text { color: var(--charcoal); }
.act-time { font-size: 11.5px; color: var(--stone); white-space: nowrap; }

/* A list that is read as prose rather than scanned as bullets: what
   Stripe will ask a landlord for, where each item is a sentence or two
   and a tight bulleted list would fight the reading. */
.plain-list { list-style: none; padding: 0; margin: 0; }
.plain-list li { margin-bottom: 12px; line-height: 1.6; }
.plain-list li:last-child { margin-bottom: 0; }
.plain-list strong { color: var(--charcoal); }

/* The payments page. A host reads this to answer four questions: what
   have I been paid, what is coming, when, and what was taken off. */
.pay-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 20px; }
.pay-grid .card { margin: 0; }
.filter-row { display: flex; gap: 12px; align-items: end; flex-wrap: wrap; }
.filter-label {
  display: block; font-size: 12px; letter-spacing: 0.03em; font-weight: 700;
  color: var(--stone); margin-bottom: 5px;
}
/* A refunded payment is still part of the record, so it is shown rather
   than dropped, but it is not money and must not read like money. */
.row-void td { opacity: 0.62; }
.row-void td strong { text-decoration: line-through; }
.mono {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 12.5px; color: var(--stone); word-break: break-all;
}

@media (max-width: 880px) {
  .kpi-row { grid-template-columns: 1fr 1fr; }
  .activity-row { grid-template-columns: 64px 1fr; }
  .act-time { display: none; }
}

/* Area directory */
.area-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 10px 24px;
}
.area-link {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  text-decoration: none;
  font-size: 15.5px;
  padding: 9px 12px;
  border-radius: 3px;
  border: 1px solid transparent;
}
.area-link:hover { background: var(--porcelain); border-color: var(--brass); color: var(--green); }
@media (max-width: 880px) {
  .area-grid { grid-template-columns: 1fr 1fr; }
}

/* Space detail: feature tiles and fact grid */
.feature-grid { display: flex; flex-wrap: wrap; gap: 10px; }
.feature-tile {
  background: var(--green);
  color: var(--porcelain);
  border-radius: 3px;
  padding: 10px 16px;
  font-size: 13.5px;
  font-weight: 600;
  letter-spacing: 0.04em;
}
.fact-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 14px 24px;
  font-size: 15px;
}
.fact-label {
  display: block;
  font-size: 11.5px;
  letter-spacing: 0.03em;
  color: var(--stone);
  font-weight: 700;
  margin-bottom: 2px;
}
#minimap {
  position: relative; /* anchors the Street View pill */
  height: 300px;
  border: 1px solid rgba(17, 19, 18, 0.2);
  border-radius: 4px;
}

/* Footer */
.site-footer {
  background: var(--charcoal);
  color: var(--porcelain);
  padding: 56px 0 40px;
  margin-top: 0;
}
.site-footer .cols { display: grid; grid-template-columns: 2fr 1fr 1fr 1fr 1fr; gap: 32px; margin-bottom: 40px; }
.site-footer .foot-label { font-weight: 700; }
.site-footer a { color: rgba(247, 243, 235, 0.75); text-decoration: none; display: block; font-size: 14.5px; margin-bottom: 8px; }
.site-footer a:hover { color: var(--brass); }
.site-footer .tag { color: rgba(247, 243, 235, 0.45); font-size: 13px; border-top: 1px solid rgba(214, 183, 123, 0.2); padding-top: 24px; }
/* The badge with the brand block, sized to the footer. The footer's
   own anchor rule (block, 8px under) is not for an image link. */
.foot-app { display: flex; align-items: center; gap: 14px; margin-top: 20px; }
/* flex: none, or the anchor gives way to the note beside it and the
   image, capped at 100% of the anchor with its height fixed, is
   squashed rather than shrunk: 107x40 at 1440px for a 3:1 badge. The
   note is prose and can wrap; Apple's badge cannot. */
.site-footer .foot-app .store-badge { display: inline-block; margin: 0; flex: none; }
.site-footer .foot-app .store-badge img { height: 40px; }
.foot-app-note { color: rgba(247, 243, 235, 0.55); font-size: 13px; margin: 0; }
/* Inside the app's own shell the invitation to download it is noise. */
html.app-shell .foot-app { display: none; }

/* Utility */
.mt-2 { margin-top: 16px; } .mt-3 { margin-top: 24px; } .mt-4 { margin-top: 36px; }
.mb-2 { margin-bottom: 16px; } .mb-3 { margin-bottom: 24px; }
.muted { color: var(--stone); }
.center { text-align: center; }
.inline-form { display: inline; }

/* A clear parent endorsement within the existing footer. */
.site-footer a.welly-footer-link { display: inline-flex; align-items: center; gap: 12px; min-height: 76px; margin: 20px 0 0; padding: 4px 0; color: var(--porcelain); }
.welly-footer-link > img { flex-shrink: 0; }
.welly-footer-copy { display: grid; gap: 3px; }
.welly-footer-label { font-size: 13px; line-height: 1.4; color: #d6d8d1; }
.welly-footer-name { font-family: var(--serif); font-size: 24px; line-height: 1.2; }
.welly-footer-explore { display: inline-flex; align-items: center; gap: 8px; font-size: 13px; line-height: 1.5; color: var(--brass); }
.welly-footer-link:hover .welly-footer-explore { text-decoration: underline; text-underline-offset: 4px; }
.welly-footer-link:focus-visible, .welly-family-cta:focus-visible, .welly-family-member:focus-visible { outline: 2px solid var(--brass); outline-offset: 5px; border-radius: 3px; }
.welly-family-section { padding: 48px 0 0; }
.welly-family-panel { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); align-items: center; gap: 58px; position: relative; overflow: hidden; padding: 42px; color: var(--porcelain); background: #163f32; border: 1px solid #42604c; border-radius: 12px; }
.welly-family-panel::after { content: ""; position: absolute; bottom: 0; left: 0; width: 100%; height: 3px; background: linear-gradient(90deg, #d6b77b, #75967b 65%, transparent); transform-origin: left; pointer-events: none; }
.welly-family-parent { display: flex; align-items: center; gap: 10px; margin: 0 0 20px; font-size: 15px; }
.welly-family-parent img { flex-shrink: 0; }
.welly-family-copy h2 { margin-bottom: 18px; font-size: clamp(32px, 3vw, 42px); }
.welly-family-copy > p:not(.welly-family-parent) { color: #e0e4d9; font-size: 15px; line-height: 1.7; max-width: 42ch; }
.welly-family-cta { display: inline-flex; align-items: center; justify-content: space-between; gap: 18px; min-height: 48px; padding: 10px 0; margin-top: 20px; border-bottom: 1px solid var(--brass); color: var(--porcelain); text-decoration: none; font-size: 15px; font-weight: 600; }
.welly-family-members { display: grid; gap: 12px; min-width: 0; }
.welly-family-member { display: flex; align-items: center; gap: 14px; min-height: 94px; min-width: 0; padding: 18px; border: 1px solid #4e6d58; border-radius: 8px; background: #1c4739; color: var(--porcelain); text-decoration: none; }
.welly-family-member > img { flex-shrink: 0; }
.welly-family-member > span { min-width: 0; }
.welly-family-member strong { font-family: var(--serif); font-size: 24px; font-weight: 500; }
.welly-family-purpose { display: block; margin-top: 4px; color: #e0e4d9; font-size: 13px; line-height: 1.5; }
.welly-family-member:hover { background: #245342; border-color: var(--brass); }
@media (prefers-reduced-motion: no-preference) {
  .welly-family-member { transition: background .2s ease, border-color .2s ease; }
  .welly-family-panel.is-in-view::after { animation: welly-family-line 1s ease both; }
  .welly-family-panel.is-in-view .welly-family-member { animation: welly-family-arrive .55s ease both; }
  .welly-family-panel.is-in-view .welly-family-member:nth-child(2) { animation-delay: .1s; }
  .welly-family-panel.is-in-view .welly-family-member:nth-child(3) { animation-delay: .2s; }
}
@keyframes welly-family-line { from { transform: scaleX(0); } to { transform: scaleX(1); } }
@keyframes welly-family-arrive { from { transform: translateY(12px); } to { transform: translateY(0); } }
@media print { .welly-family-section { display: none; } }

@media (max-width: 880px) {
  .wrap { padding: 0 18px; }
  .welly-family-section { padding-top: 28px; }
  .welly-family-panel { grid-template-columns: minmax(0, 1fr); gap: 28px; padding: 24px 20px; }
  .welly-family-copy h2 { font-size: 34px; }
  .welly-family-parent { font-size: 14px; gap: 8px; }
  .welly-family-member { padding: 16px 12px; gap: 10px; }
  .welly-family-member > img { width: 36px; height: 36px; }
  .welly-family-member strong { font-size: 22px; }
  .welly-family-purpose { font-size: 12px; }


  /* One row: wordmark at one end, who you are and the burger at the
     other, and the site links folded behind it. The header was three
     rows deep and about 230px tall on a phone, which is a third of the
     screen gone before the map starts. */
  .site-header .wrap {
    flex-direction: row;
    flex-wrap: wrap;
    align-items: center;
    gap: 10px;
    padding-top: 8px;
    padding-bottom: 8px;
    min-height: 0;
  }
  /* Source order is wordmark, nav, then who you are; on a phone the nav
     is a full-width panel, so it has to come last or it breaks the line
     before the burger and the header is two rows again. */
  .wordmark { order: 1; font-size: 20px; margin-right: auto; }
  .head-right { order: 2; gap: 10px; }
  .site-header .main-nav { order: 3; }
  .logo-mark { width: 28px; height: 28px; margin-right: 8px; }
  .on-wide { display: none; }
  .in-burger { display: inline-block; }
  .my-storewelly { padding: 8px 12px; font-size: 13.5px; gap: 6px; }
  .my-storewelly svg { width: 15px; height: 15px; }

  .burger {
    display: flex;
    flex-direction: column;
    justify-content: center;
    gap: 5px;
    width: 42px;
    height: 42px;
    padding: 0 9px;
    background: none;
    border: 1px solid rgba(214, 183, 123, 0.45);
    border-radius: 4px;
    cursor: pointer;
  }
  .burger span {
    display: block;
    height: 2px;
    background: var(--brass);
    border-radius: 2px;
    transition: transform 0.18s ease, opacity 0.15s ease;
  }
  .burger[aria-expanded="true"] span:nth-child(1) { transform: translateY(7px) rotate(45deg); }
  .burger[aria-expanded="true"] span:nth-child(2) { opacity: 0; }
  .burger[aria-expanded="true"] span:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }

  /* The panel takes the full width under the row. Until the script
     collapses it, it is simply the nav, so no JavaScript means the whole
     menu rather than none of it. */
  .site-header.js-nav .main-nav {
    flex-basis: 100%;
    flex-direction: column;
    align-items: stretch;
    gap: 0;
    max-height: 0;
    overflow: hidden;
    transition: max-height 0.22s ease;
  }
  .site-header.js-nav .main-nav a {
    padding: 13px 2px;
    font-size: 16px;
    border-top: 1px solid rgba(214, 183, 123, 0.18);
  }
  .site-header.js-nav .main-nav a.nav-cta {
    margin: 12px 0 4px;
    text-align: center;
    padding: 12px;
    border: 1px solid var(--brass);
  }
  .site-header.js-nav.nav-open .main-nav { max-height: 60vh; overflow: auto; }
  .main-nav a { font-size: 13.5px; }
  .user-box { padding: 6px 12px; font-size: 13.5px; }
  /* Hover cannot open a menu on a touch screen, so the chip toggles it
     and the dropdown hangs off the right edge where there is room. */
  .user-menu.open .user-drop { display: block; }
  .user-drop { right: 0; left: auto; }

  .hero-inner { padding: 40px 0 30px; }
  /* The brass CTA under the lede duplicates the search panel that is
     the very next thing on the page. On a phone it was what pushed the
     panel's own Search button under the 844px fold, so the card the
     visitor came for needed a scroll before it could be used. Hidden
     here, the whole panel, button included, fits the first screen. */
  .hero-inner .btn { display: none; }
  .hero p.lede { margin-bottom: 0; }
  .hero h1 { font-size: 40px; }
  .search-panel { grid-template-columns: 1fr; }
  .search-panel .field { border-right: none; border-bottom: 1px solid rgba(17, 19, 18, 0.12); }
  .grid-3, .grid-2, .grid-detail, .space-grid { grid-template-columns: 1fr; }
  .stat-row { grid-template-columns: 1fr 1fr; gap: 12px; }
  .stat { padding: 16px; }
  .stat .n { font-size: 26px; }

  /* One line standing in for two rows of controls, with what is being
     searched written on it. Tapping it drops the real controls down. */
  .search-more-toggle {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    width: 100%;
    margin-top: 8px;
    padding: 11px 14px;
    background: var(--porcelain);
    border: 1px solid rgba(17, 19, 18, 0.16);
    border-radius: 4px;
    font-family: var(--sans);
    font-size: 15px;
    font-weight: 600;
    color: var(--charcoal);
    cursor: pointer;
  }
  .search-more-toggle span {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }
  /* First thing on the search row, in brass. Icon over label so it
     stays narrow enough to leave the destination box usable. */
  .view-toggle {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 1px;
    flex: none;
    width: 54px;
    padding: 5px 4px;
    background: var(--brass);
    border: 1px solid var(--brass);
    border-radius: 4px;
    font-family: var(--sans);
    font-size: 10.5px;
    font-weight: 700;
    letter-spacing: 0.02em;
    color: var(--charcoal);
    cursor: pointer;
  }
  .view-toggle:active { background: var(--porcelain); }
  .view-toggle svg { width: 19px; height: 19px; flex: none; }
  .view-toggle .ico-map { display: none; }
  .view-toggle[aria-pressed="true"] .ico-list { display: none; }
  .view-toggle[aria-pressed="true"] .ico-map { display: block; }
  .search-layout.list-view .search-map { display: none; }
  .search-layout.list-view .search-list { max-height: none; }
  .search-more-toggle svg { width: 18px; height: 18px; flex: none; transition: transform 0.2s ease; }
  .search-more-toggle[aria-expanded="true"] svg { transform: rotate(180deg); }
  .side-search.js-fold .side-search-more {
    max-height: 0;
    overflow: hidden;
    transition: max-height 0.24s ease;
  }
  .side-search.js-fold.more-open .side-search-more { max-height: 70vh; overflow: visible; }

  /* The card for a tapped pin floats over the bottom of the map rather
     than replacing the list underneath it. It was landing below the
     fold, so tapping a pin appeared to do nothing until you scrolled. */
  .space-panel:not([hidden]) {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 900;
    max-height: 30vh;
    padding: 14px 16px calc(16px + env(safe-area-inset-bottom, 0px));
    border-top: 1px solid rgba(17, 19, 18, 0.16);
    border-radius: 12px 12px 0 0;
    box-shadow: 0 -10px 30px rgba(17, 19, 18, 0.28);
    animation: sp-rise 0.22s ease;
  }
  @keyframes sp-rise { from { transform: translateY(100%); } to { transform: none; } }
  /* The card is a summary, not the listing. Title, photo, price and the
     way in; everything else is one tap away on the listing itself, and
     leaving it here pushed the button off the bottom and took half the
     map with it. */
  /* Photo down the left, the words beside it, the way in across the
     bottom. A card, not a page: everything else is one tap away on the
     listing itself. */
  .space-panel:not([hidden]) {
    display: grid;
    grid-template-columns: 108px 1fr;
    grid-template-rows: auto auto auto 1fr;
    column-gap: 12px;
    align-content: start;
  }
  .space-panel .sp-carousel {
    grid-area: 1 / 1 / 4 / 2;
    margin: 0;
    align-self: start;
  }
  .space-panel .sp-carousel img { height: 96px; object-fit: cover; }
  .space-panel .sp-head { grid-column: 2; }
  .space-panel .sp-head h3 { font-size: 15.5px; line-height: 1.25; }
  .space-panel .sp-meta { grid-column: 2; font-size: 12px; margin-top: 2px; }
  .space-panel .sp-price { grid-column: 2; font-size: 23px; margin-top: 4px; }
  .space-panel .sp-pills { grid-column: 1 / -1; margin-top: 8px; }
  .space-panel .btn { grid-column: 1 / -1; margin-top: 8px; padding: 11px; }
  .space-panel .sp-desc,
  .space-panel .sp-features,
  .space-panel .sp-short,
  .space-panel .sp-arrow,
  .space-panel .sp-dots { display: none; }
  @media (prefers-reduced-motion: reduce) {
    .space-panel:not([hidden]) { animation: none; }
  }

  /* Search page flows as one scroll: search, map, then the list */
  .search-layout { display: flex; flex-direction: column; height: auto; min-height: 0; }
  .search-sidebar { display: contents; }
  .side-search { order: 1; }
  /* The map is what people came for, so it gets whatever the header and
     the one control row leave. Roughly two thirds of a phone screen,
     against the 340px it had when three rows of controls sat above it. */
  .search-map { order: 2; height: 62vh; min-height: 340px; }
  #map { border-left: none; }
  .search-list { order: 3; max-height: none; overflow: visible; background: var(--parchment); }
  .space-panel { order: 3; overflow: visible; }
  /* Keep Search this area clear of the style switcher on small maps */
  .map-area-btn { top: auto; bottom: 16px; }

  .section { padding: 52px 0; }
  /* The first screen ends on the search card, and the section after the
     hero opened with a 124px parchment void before its heading: on an
     app open that read as the page running out. Tightened only for the
     section that directly follows the hero, so the fold shows the next
     heading arriving instead of a gap. */
  .hero + .section { padding-top: 24px; }
  /* The other 72px of that void was the search panel's own bottom
     margin spilling out of the hero as bare parchment. Matches the
     specificity of the laptop rule (.hero .search-panel) or it loses
     the cascade to it. */
  .hero .search-panel { margin-bottom: 16px; }
  .page-head { padding: 40px 0 36px; }
  .form-card { padding: 24px 20px; }
  .hub-nav { gap: 2px; }
  .hub-nav a { padding: 7px 10px; font-size: 12px; }
  .site-footer .cols { grid-template-columns: 1fr 1fr; }
  .form-split { grid-template-columns: 1fr; }
  .fact-grid { grid-template-columns: 1fr; }
}

/* Listing photo carousel: full column width, one photo at a time */
.photo-carousel { position: relative; overflow: hidden; border-radius: 4px; }
.carousel-track { display: flex; transition: transform 0.35s ease; }
.carousel-slide { flex: 0 0 100%; }
.carousel-slide img {
  width: 100%;
  aspect-ratio: 16 / 10;
  object-fit: cover;
  display: block;
}
.carousel-btn {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  width: 42px;
  height: 42px;
  border-radius: 50%;
  background: rgba(17, 19, 18, 0.72);
  color: var(--brass);
  border: 1px solid var(--brass);
  font-size: 26px;
  line-height: 1;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  padding-bottom: 4px;
}
.carousel-prev { left: 12px; }
.carousel-next { right: 12px; }
.carousel-btn:hover { background: var(--green); }
.carousel-dots {
  position: absolute;
  bottom: 12px;
  left: 0;
  right: 0;
  display: flex;
  justify-content: center;
  gap: 7px;
}
.carousel-dot {
  width: 9px;
  height: 9px;
  border-radius: 50%;
  border: 1px solid var(--brass);
  background: rgba(17, 19, 18, 0.55);
  cursor: pointer;
  padding: 0;
}
.carousel-dot.active { background: var(--brass); }

/* Minimap attribution: the compact info button, dressed properly */
#minimap .mapboxgl-ctrl-attrib-button {
  width: 26px;
  height: 26px;
  background-color: var(--charcoal);
  border: 1px solid var(--brass);
  border-radius: 50%;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Ccircle cx='12' cy='5' r='1.9' fill='%23D6B77B'/%3E%3Crect x='10.3' y='9' width='3.4' height='11' rx='1.7' fill='%23D6B77B'/%3E%3C/svg%3E");
  background-size: 12px 12px;
  background-repeat: no-repeat;
  background-position: center;
  opacity: 0.92;
}
#minimap .mapboxgl-ctrl-attrib-button:hover { opacity: 1; background-color: var(--green); }
#minimap .mapboxgl-ctrl-attrib.mapboxgl-compact { background: transparent; }
#minimap .mapboxgl-ctrl-attrib.mapboxgl-compact-show {
  background: rgba(17, 19, 18, 0.88);
  border-radius: 14px;
  color: rgba(247, 243, 235, 0.85);
}
#minimap .mapboxgl-ctrl-attrib.mapboxgl-compact-show .mapboxgl-ctrl-attrib-inner { color: rgba(247, 243, 235, 0.85); }
#minimap .mapboxgl-ctrl-attrib a { color: var(--brass); }

/* Fleet dashboard preview on the business page: drawn in-brand, no image */
.fleet-mock {
  background: var(--charcoal-soft);
  border: 1px solid rgba(214, 183, 123, 0.4);
  border-radius: 6px;
  padding: 22px;
  font-size: 13.5px;
  box-shadow: 0 14px 40px rgba(0, 0, 0, 0.35);
}
.fleet-mock-head {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  font-family: var(--serif);
  font-size: 17px;
  border-bottom: 1px solid rgba(214, 183, 123, 0.25);
  padding-bottom: 12px;
}
.fleet-mock-ref { font-family: var(--sans); font-size: 11px; color: var(--brass); letter-spacing: 0.08em; }
.fleet-mock-stats { display: flex; gap: 26px; padding: 16px 0; }
.fleet-mock-stats .n { display: block; font-family: var(--serif); font-size: 24px; color: var(--brass); }
.fleet-mock-stats .l { font-size: 11px; color: rgba(247, 243, 235, 0.6); }
.fleet-mock-row {
  display: flex;
  justify-content: space-between;
  padding: 9px 0;
  border-top: 1px solid rgba(247, 243, 235, 0.08);
  color: rgba(247, 243, 235, 0.85);
}
.fleet-mock-row span:last-child { color: rgba(247, 243, 235, 0.55); }
.fleet-mock-foot {
  margin-top: 12px;
  padding-top: 12px;
  border-top: 1px solid rgba(214, 183, 123, 0.25);
  font-size: 11.5px;
  color: var(--brass);
  letter-spacing: 0.04em;
}
.business-form-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
@media (max-width: 880px) {
  .business-form-grid { grid-template-columns: 1fr; }
}


/* Deep-dive polish */
/* iOS Safari zooms the page when focusing a control under 16px */
@media (max-width: 880px), (pointer: coarse) {
  .side-search-row select,
  .filter-row2 select,
  .filter-row2 input,
  .side-search-dates input[type=date],
  .side-search-dates input[type=datetime-local],
  .side-search-dates select,
  .side-search-dest input { font-size: 16px; }
  .side-search-dates input[type=date],
  .side-search-dates input[type=datetime-local],
  .side-search-dates select { flex: 1 1 45%; }
  .map-style-ctl button { padding: 10px 12px; }
  .nearby-chip { padding: 9px 14px; font-size: 13px; }
  .filter-grid label { min-height: 42px; }
  .filter-grid input[type="checkbox"] { width: 19px; height: 19px; }
  .carousel-dot { width: 11px; height: 11px; position: relative; }
  .carousel-dot::before {
    content: "";
    position: absolute;
    left: -10px;
    top: -10px;
    right: -10px;
    bottom: -10px;
  }
  .carousel-btn { width: 46px; height: 46px; }
}
/* Booking-type tabs on the book page */
.type-tabs { display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 6px; }
.type-tab {
  font-size: 13.5px;
  font-weight: 600;
  padding: 7px 14px;
  border: 1px solid rgba(17, 19, 18, 0.2);
  border-radius: 3px;
  text-decoration: none;
  color: var(--charcoal);
}
.type-tab:hover { border-color: var(--brass); }
.type-tab.active { background: var(--green); color: var(--porcelain); border-color: var(--green); }

/* Host onboarding checklist */
.onboard-card { border-top: 3px solid var(--brass); }
.onboard-head { display: flex; justify-content: space-between; align-items: baseline; }
.onboard-count { font-size: 13px; color: var(--stone); font-weight: 600; }
.onboard-bar {
  height: 5px;
  background: rgba(17, 19, 18, 0.1);
  border-radius: 3px;
  margin: 12px 0 18px;
  overflow: hidden;
}
.onboard-bar span { display: block; height: 100%; background: var(--brass); transition: width 0.4s ease; }
.onboard-steps { list-style: none; margin: 0; padding: 0; }
.onboard-steps li { display: flex; gap: 14px; padding: 12px 0; border-top: 1px solid rgba(17, 19, 18, 0.08); }
.onboard-steps li:first-child { border-top: none; }
.onboard-tick {
  flex: 0 0 26px;
  height: 26px;
  border-radius: 50%;
  border: 1px solid rgba(17, 19, 18, 0.25);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 13px;
  font-weight: 700;
  color: var(--stone);
}
.onboard-steps li.done .onboard-tick { background: var(--green); border-color: var(--green); color: var(--brass); }
.onboard-steps li.waiting .onboard-tick { border-color: var(--brass); color: var(--brass); }
.onboard-steps li.done strong { color: var(--stone); }

/* Unverified email reminder */
.verify-banner { background: var(--green); color: var(--porcelain); font-size: 14px; }
.verify-banner .wrap {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding-top: 10px;
  padding-bottom: 10px;
  flex-wrap: wrap;
}
.verify-banner form { margin: 0; }


/* While the boot is in the air, the closed claw wins over whatever cursor
   Mapbox puts on the canvas. !important beats their inline style. */
.boot-dragging,
.boot-dragging *,
.boot-dragging .mapboxgl-canvas-container,
.boot-dragging .mapboxgl-canvas {
  cursor: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACQAAAAkCAYAAADhAJiYAAADZElEQVR4nOyXX0hTURzHf+fO3NK53c0/K//g3/zH+sMeMsOeKjARKkR6iIhaT0H10kP0FEFQb4OCXszopYgQs39ElEmCSkYEpaapICbb0u3ezbHNNXc650yuRg/r3Kvgwz7j7Jzf7+zufPnd3/ndczNAI2KueBxhdIKOMcKPZZ/cDRpAoAHRKp5BSOjclmdktmchBBgnzsp++T6oRAAtIHS0tFCELtcp1uiY+kAD2gQBmIttZsUospmYDzSQAZuMtKBUbDpBWpMayoospAABa2ysER2oBGNAOunI9ZOtDjOrZqTttZdArpglvBv47gKVqC6Mo6+vXiKl2SWHYzA09Yv5GqsKwLw1ExCGC3UtN+6AClQJmnlxxRISBDeJkr7V9RbCsTjzGw0Z8OziIfqvYT1kbt/Rci0InKjKobCga0II6b/M+hQxlFA0Dt/mJBAQyoqjWCOoQJUgDAmWe1uEfy8XhGTQEWA9qECVoLsPB3y031lihfJ8o+KvLMgB+8pOu/1oYB5UoGqXTcwGL+t0qGFPbSEcc5QSISZothfB+YN1bP5e1zA86PkciEaib4ATNRHKQgJyeslRg4JJZh+otkFDZT4b049nYZHcMuEc/S1wwi2IHMicdKH25l3MjkRjcKujD26StrQUJ0IQtB220yQyWSyW08CJigihNjupNxXFVma9/DAOPe9H4XnfGLzqH2e+2ooCqKsgERNQG3DCK4jsIdTQ5ChXHL1Dk7TrJ/drsPfjlOJvcpTRIrefdw2uH4uiuJt0hpryPGbHlxMwwqo0eprA0DMy6WU+SnVZPu22Gi2Weo4l+ASRYriP9vWVNmaP/PDAMlGCMB6GRGI49nsZxqaTj5GasqRoHUJcBZJLEHmrqMo2ZIIxK1nzpklVJjsrIUnSp0AgMEh9M3N+NpcrZoM+U0fuMa7kWII3hwSzKWe1AMvBMI2ahwwjtJEtPy8Fo8q8KdtAO64zNm9Sm81Gg2JIgSh9jsir00iWgpE1gvR0nksQ74nxb0GLYfKN1wgC2b9GUI6RRXNDIxSacUuKQXcVSWmv4sDw8+uEWzHd80E6vwQccJ2HzFarkxSiDltu8oHq9bE3VSd5U+38n/l1F7SyaDu5iDQcTwDqDvj9T3jm113QRpN+L0tFWlAq0oJS8QcAAP//2LiErgAAAAZJREFUAwDqLyVGS/3/rQAAAABJRU5ErkJggg==") 18 13, grabbing !important;
}

/* Preview banner: a host looking at their own listing before it is live */
.preview-banner { background: var(--brass); color: var(--charcoal); font-size: 14px; }
.preview-banner .wrap {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding-top: 10px;
  padding-bottom: 10px;
  flex-wrap: wrap;
}
.preview-banner .btn { background: var(--charcoal); color: var(--brass); }
.preview-banner .btn:hover { background: var(--green); }

/* Photos found on an imported listing, offered for the host to keep */
.import-photo-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 12px; }
.import-photo { display: block; font-size: 12.5px; cursor: pointer; }
.import-photo img {
  width: 100%;
  aspect-ratio: 4 / 3;
  object-fit: cover;
  border-radius: 3px;
  border: 1px solid rgba(17, 19, 18, 0.15);
}
.import-photo span { display: flex; align-items: center; gap: 6px; margin-top: 6px; }

/* Choosing how to list: import first, blank form second */
.start-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 22px; max-width: 980px; }
/* min-width: 0 because a grid item defaults to min-width: auto, which
   means it cannot shrink below its own content: one long unbreakable
   word inside the card, such as a domain badged from an unrecognised
   platform, widened the card past its column and pushed the page 220px
   sideways on a phone. */
.start-card { display: flex; flex-direction: column; min-width: 0; }
.start-card form, .start-card > a.btn { margin-top: auto; }
@media (max-width: 800px) { .start-grid { grid-template-columns: 1fr; } }
.start-card input[type="url"],
.start-card textarea { width: 100%; box-sizing: border-box; padding: 11px 12px; border: 1px solid rgba(17,19,18,0.25); border-radius: 3px; font-size: 15px; font-family: inherit; background: #fff; }
.start-card textarea { min-height: 110px; }
.start-card .form-row { margin-top: 12px; }


/* Pasted listing links, as badges. The box looks like the text field it
   replaces, so nothing about the form reads differently; the input sits
   inside it and grows to whatever room is left on the line. */
.link-chips {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  padding: 8px;
  border: 1px solid rgba(17, 19, 18, 0.25);
  border-radius: 3px;
  background: #fff;
  cursor: text;
}
.link-chips:focus-within { border-color: var(--green); }
.link-chip-set { display: contents; }
.link-chip {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  background: var(--green);
  color: var(--porcelain);
  border-radius: 3px;
  padding: 0 2px 0 11px;
  font-size: 13.5px;
  font-weight: 600;
  min-height: 40px;
  /* A platform we do not know is badged by its domain, and one long
     domain used to push the whole page sideways: 209px of horizontal
     scroll on a phone. min-width on the flex child is what actually
     lets the ellipsis happen. */
  max-width: 100%;
  min-width: 0;
}
.link-chip-name {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  min-width: 0;
}
.link-chip-drop {
  border: 0;
  background: transparent;
  color: var(--brass);
  font-size: 18px;
  line-height: 1;
  cursor: pointer;
  /* 40px square: the house floor for anything a thumb presses. */
  min-width: 40px;
  min-height: 40px;
  flex: 0 0 auto;
}
.link-chip-drop:hover { color: var(--porcelain); }
/* .start-card names input[type=url] and input[type=text], which outranks
   a bare class, so this has to say the card too or the field draws as a
   bordered white box inside the bordered white box it sits in. */
.link-chips .link-chip-input,
.start-card .link-chips .link-chip-input {
  flex: 1 1 170px;
  min-width: 120px;
  border: 0;
  outline: none;
  padding: 8px 4px;
  margin: 0;
  font-family: var(--sans);
  font-size: 16px;
  background: transparent;
  box-shadow: none;
}

/* A label that is itself the tick-box row. .form-row label sets
   display:block, which outranks .checkbox-row's flex, so above phone
   width the box and its sentence rendered touching. The phone rules
   lay the same label out as a flex row with its own gap. */
@media (min-width: 881px) {
  label.checkbox-row input[type="checkbox"] { margin-right: 8px; }
}

/* Search, sort and filter above a back-office table. Built by
   tabletools.js, so none of it exists without JavaScript. */
.table-tools { margin-bottom: 12px; }
.table-tools-row { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
.table-tools-search { flex: 1 1 220px; min-width: 160px; }
.table-tools-sort {
  flex: 0 1 auto;
  padding: 10px 34px 10px 12px;
  border: 1px solid rgba(17, 19, 18, 0.25);
  border-radius: 3px;
  font-size: 15px;
  min-height: 40px;
}
.table-tools-dir { white-space: nowrap; }
.table-tools-panel {
  display: flex;
  flex-wrap: wrap;
  gap: 10px 26px;
  margin-top: 10px;
  padding: 14px 16px;
  background: var(--porcelain);
  border: 1px solid rgba(17, 19, 18, 0.14);
  border-radius: 4px;
}
.table-tools-group { min-width: 150px; }
.table-tools-choice { font-size: 14px; display: flex; align-items: center; gap: 8px; }
.table-tools-count { font-size: 13px; color: var(--stone); margin-top: 8px; }
/* A header that sorts says so, and says which way. */
.data-table th.is-sortable { cursor: pointer; user-select: none; white-space: nowrap; }
.data-table th.is-sortable:hover { color: var(--brass); }
.data-table th.is-sortable::after {
  content: "";
  display: inline-block;
  width: 0;
  height: 0;
  margin-left: 6px;
  border-left: 4px solid transparent;
  border-right: 4px solid transparent;
  border-top: 5px solid currentColor;
  opacity: 0.25;
}
.data-table th.is-sorted::after { opacity: 1; color: var(--brass); }
.data-table th.is-sorted.is-desc::after {
  border-top: 0;
  border-bottom: 5px solid currentColor;
}

/* The host dashboard's action row, directly under the figures. */
.host-actions { display: flex; gap: 10px; flex-wrap: wrap; }

/* The pricing table: four number boxes of the same width, so the figures
   line up down the page and the listing title gets the room that is left
   rather than wrapping to five lines beside empty columns. */
.price-table th:first-child, .price-table td:first-child { width: 34%; }
.price-table th:not(:first-child), .price-table td:not(:first-child) { width: 16.5%; }
.price-table .price-box { width: 100%; text-align: right; }

/* Form dropdowns: solid brass triangle, pulled in from the edge, matching
   the map's Monthly pass and Nearest first dropdowns */
.form-card select,
.form-wide select,
/* Any select in a house form row or a card: the convention is the
   triangle everywhere, and naming only two containers meant the review
   form's rating dropdown wore the browser's chevron instead. */
.form-row select,
.card select {
  appearance: none;
  -webkit-appearance: none;
  padding-right: 34px;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='7'%3E%3Cpath d='M0 0h10L5 7z' fill='%23D6B77B'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 14px center;
  background-size: 10px 7px;
}


/* Street View link in the corner of the listing minimap */
.sv-pill {
  position: absolute;
  right: 10px;
  bottom: 10px;
  z-index: 5;
  height: 26px;
  display: inline-flex;
  align-items: center;
  box-sizing: border-box;
  background: var(--charcoal);
  color: var(--brass);
  border: 1px solid var(--brass);
  border-radius: 13px;
  padding: 0 11px;
  font-family: var(--sans);
  font-size: 11px;
  font-weight: 700;
  text-decoration: none;
  box-shadow: 0 2px 6px rgba(17, 19, 18, 0.35);
}
.sv-pill:hover { background: var(--green); color: var(--porcelain); }


/* Attribution info button sits just left of the Street View pill */
#minimap .mapboxgl-ctrl-bottom-right { right: 96px; bottom: 2px; }

/* Four narrow fields on one line: reg, make, model, colour */
.form-split-4 { display: grid; grid-template-columns: 1.2fr 1fr 1fr 0.9fr; gap: 12px; }
@media (max-width: 700px) { .form-split-4 { grid-template-columns: 1fr 1fr; } }

/* Pause / Cancel: solid stone from the brand palette, same size as the
   other row buttons */
.btn-stone { background: var(--stone); color: var(--porcelain); border: none; }
.btn-stone:hover { background: var(--charcoal); color: var(--brass); }

/* Admin action rows: solid palette colours, one height, wrapping instead
   of running off the table edge */
.admin-actions { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; }
.admin-actions .inline-form { display: contents; }
.btn-green { background: var(--green); color: var(--porcelain); border: none; }
.btn-green:hover { background: var(--charcoal); color: var(--brass); }
.btn-terracotta { background: var(--terracotta); color: var(--porcelain); border: none; }
.btn-terracotta:hover { background: var(--charcoal); color: var(--brass); }


/* CONVENTION: buttons that sit in a table row's action column are all
   the same height and the same width, so every row's buttons line up in
   columns no matter what they say. Applies to host and admin tables
   alike; use .btn-small inside a .data-table cell or .admin-actions and
   the sizing is handled. Keep new tables to this convention. */
.data-table td .btn-small,
.admin-actions .btn-small,
.btn-fixed {
  min-width: 112px;   /* fits the longest row label (Fetch photos) */
  height: 34px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  box-sizing: border-box;
  padding: 0 12px;
  text-align: center;
}

/* CONVENTION: a row keeps its primary actions visible and puts the rest
   behind one More menu, so rows never grow past a couple of buttons.
   Plain details/summary, so it works without JavaScript. */
.more-menu { position: relative; display: inline-block; }
.more-menu > summary { list-style: none; cursor: pointer; }
.more-menu > summary::-webkit-details-marker { display: none; }
.more-menu[open] > summary { background: var(--charcoal); color: var(--brass); }
.more-menu-items {
  position: absolute;
  right: 0;
  top: calc(100% + 4px);
  z-index: 30;
  min-width: 210px;
  background: var(--porcelain);
  border: 1px solid rgba(17, 19, 18, 0.18);
  border-radius: 3px;
  box-shadow: 0 8px 22px rgba(17, 19, 18, 0.18);
  padding: 6px;
  display: flex;
  flex-direction: column;
  gap: 2px;
  text-align: left;
}
.more-menu-items a,
.more-menu-items button {
  display: block;
  width: 100%;
  background: none;
  border: none;
  text-align: left;
  font-family: var(--sans);
  font-size: 13.5px;
  color: var(--charcoal);
  text-decoration: none;
  padding: 9px 10px;
  border-radius: 2px;
  cursor: pointer;
}
.more-menu-items a:hover,
.more-menu-items button:hover { background: var(--parchment); color: var(--green); }

/* Photo manager: drag the tiles to reorder, first one is the main photo.
   No buttons under the tiles: delete lives on the photo itself. */
.photo-manager {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(190px, 1fr));
  gap: 14px;
  margin-top: 10px;
  touch-action: none;          /* a finger drags tiles, not the page */
}
.photo-manager.is-saving { opacity: 0.75; }
.photo-tile {
  margin: 0;
  position: relative;
  border: 1px solid rgba(17, 19, 18, 0.15);
  border-radius: 4px;
  overflow: hidden;
  background: var(--porcelain);
  cursor: grab;
  user-select: none;
  transition: box-shadow 0.15s ease, transform 0.15s ease;
}
.photo-tile img {
  display: block;
  width: 100%;
  aspect-ratio: 4 / 3;
  object-fit: cover;
  pointer-events: none;        /* the tile is the drag handle, not the image */
}
.photo-tile.is-dragging {
  cursor: grabbing;
  opacity: 0.85;
  transform: scale(1.03);
  box-shadow: 0 12px 26px rgba(17, 19, 18, 0.28);
  z-index: 5;
}
.photo-tile.is-main { border-color: var(--brass); box-shadow: 0 0 0 2px var(--brass); }
.photo-badge {
  position: absolute;
  top: 8px;
  left: 8px;
  display: none;
  background: var(--brass);
  color: var(--charcoal);
  font-family: var(--sans);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.04em;
  padding: 4px 9px;
  border-radius: 999px;
}
.photo-tile.is-main .photo-badge { display: block; }
.photo-delete {
  position: absolute;
  right: 8px;
  bottom: 8px;
  width: 28px;
  height: 28px;
  display: flex;
  align-items: center;
  justify-content: center;
  border: none;
  border-radius: 50%;
  background: rgba(17, 19, 18, 0.62);
  color: var(--porcelain);
  font-size: 17px;
  line-height: 1;
  cursor: pointer;
  opacity: 0;
  transition: opacity 0.15s ease, background 0.15s ease;
}
.photo-tile:hover .photo-delete,
.photo-delete:focus { opacity: 1; }
.photo-delete:hover { background: var(--terracotta); }
@media (hover: none) { .photo-delete { opacity: 1; } }

/* A field the form has switched off, so it reads as inert rather than
   as something the host has failed to fill in. */
.form-row input:disabled,
.form-row select:disabled {
  background: rgba(17, 19, 18, 0.05);
  color: var(--stone);
  cursor: not-allowed;
}

/* Setting the main photo without a mouse. Dragging a tile to the front
   does the same thing, but a keyboard cannot drag. */
.photo-main {
  position: absolute;
  left: 8px;
  bottom: 8px;
  border: none;
  border-radius: 999px;
  background: rgba(17, 19, 18, 0.62);
  color: var(--porcelain);
  font-family: var(--sans);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.04em;
  line-height: 1;
  padding: 7px 11px;
  cursor: pointer;
  opacity: 0;
  transition: opacity 0.15s ease, background 0.15s ease;
}
.photo-tile:hover .photo-main,
.photo-main:focus { opacity: 1; }
.photo-main:hover { background: var(--brass); color: var(--charcoal); }
.photo-tile.is-main .photo-main { display: none; }
@media (hover: none) { .photo-main { opacity: 1; } }

/* Picked but past the number this submission will take. Shown rather
   than dropped, so the host chooses which ones go. */
.photo-tile.is-over { opacity: 0.45; border-style: dashed; }
.photo-tile.is-over::after {
  content: "Will not upload";
  position: absolute;
  inset: auto 0 0 0;
  background: rgba(17, 19, 18, 0.72);
  color: var(--porcelain);
  font-family: var(--sans);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-align: center;
  padding: 5px 0;
}
/* A browser that will not take an assigned file list cannot reorder,
   so the tiles stop inviting it. */
.photo-manager.is-fixed .photo-tile { cursor: default; }
.photo-manager.is-fixed .photo-main,
.photo-manager.is-fixed .photo-delete,
.photo-manager.is-fixed .photo-badge { display: none; }

/* A day where some but not all of a listing's spaces are let */
.cal-table td.part-booked { background: rgba(214, 183, 123, 0.22); }

/* Rate tabs on a listing: Monthly / Daily / Hourly, so the price shown
   never depends on how the driver arrived at the page */
.rate-tabs { display: flex; gap: 6px; margin-bottom: 14px; }
.rate-tab {
  flex: 1;
  padding: 9px 8px;
  border: 1px solid rgba(17, 19, 18, 0.2);
  border-radius: 3px;
  background: var(--porcelain);
  color: var(--charcoal);
  font-family: var(--sans);
  font-size: 13.5px;
  font-weight: 700;
  cursor: pointer;
}
.rate-tab:hover { border-color: var(--green); }
.rate-tab.active { background: var(--green); color: var(--porcelain); border-color: var(--green); }

/* --- Phone corrections, applied nowhere else -----------------------
   The site was laid out on a laptop and made to fit a phone
   afterwards, which leaves the same handful of faults every time:
   fields that make iOS zoom, and controls sized for a mouse. They are
   collected here at the end rather than scattered, so nothing in the
   desktop rules above has to change and nothing here can reach a
   laptop. Written for a phone first, since that is where the traffic
   is and where the app will start. */
@media (max-width: 880px) {
  /* Sixteen pixels is not a taste: below it, iOS zooms the page the
     moment a field is focused and never zooms back, so the rest of
     the form ends up off the side of the screen. Every field. */
  input[type=text], input[type=email], input[type=password],
  input[type=number], input[type=tel], input[type=search],
  input[type=date], input[type=datetime-local], input[type=time],
  input[type=url], select, textarea,
  /* An input with no type attribute is a text field, and the attribute
     selectors above do not match it: it keeps the 13.3px UA default. */
  input:not([type]) { font-size: 16px; }
  /* These four carry a smaller size from a rule specific enough to win
     the blanket one above. Left at their laptop sizes, raised here. */
  .search-panel input[type=datetime-local],
  .watch-strip input[type=email],
  .start-card textarea, .start-card input[type="url"],
  .inline-field, .inline-field-tight, .inline-field-sm,
  .inline-field-dark, .table-tools-sort { font-size: 16px; }

  /* iOS paints the text caret and the tick boxes system blue, the one
     colour the palette does not contain. The caret takes the brand
     green, brass on the one dark field; ticks and radios take the
     brass the filter panel already uses, so every checked box on the
     site agrees. */
  input, textarea { caret-color: var(--green); }
  .inline-field-dark { caret-color: var(--brass); }
  input[type="checkbox"], input[type="radio"] { accent-color: var(--brass); }

  /* A thumb is about 44px across. Anything meant to be pressed gets
     that much height, whatever its label needs. */
  /* The footer was a two column grid, so every row was as tall as its
     tallest cell: Hosts has three links and Company has six, which left
     half a screen of nothing under Hosts, and Popular areas sat in one
     column with the other half of the width empty beside it. Two
     screens of footer, mostly gaps (Henry, 2026-08-17).

     One group per row instead, each a wrapped row of chips. Nothing has
     to line up with anything, so there are no gaps to leave; every link
     is a thumb-sized target rather than a 23px line of text; and the
     whole footer reads as one system rather than a laptop's columns
     folded in half.  */
  .site-footer .cols { display: block; margin-bottom: 20px; }
  .site-footer .cols > div { margin-bottom: 16px; }
  .site-footer .cols > div:not(:first-child) {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
  }
  .site-footer .foot-label { margin-bottom: 2px; }
  .site-footer .cols > div:not(:first-child) .foot-label { flex: 1 0 100%; }
  .site-footer .cols a:not(.wordmark):not(.welly-footer-link) {
    display: inline-flex;
    align-items: center;
    min-height: 40px;
    margin-bottom: 0;
    padding: 0 14px;
    border: 1px solid rgba(214, 183, 123, 0.28);
    border-radius: 3px;
    font-size: 14.5px;
    line-height: 1.2;
  }
  .site-footer .cols a:not(.wordmark):not(.welly-footer-link):hover { border-color: var(--brass); }

  .wordmark { min-height: 44px; }
  .my-storewelly { min-height: 44px; }
  .head-login { display: inline-flex; align-items: center; min-height: 44px; }
  .burger { width: 44px; height: 44px; }

  /* Mapbox draws its controls at 29px, which is a mouse target. The
     icons are background images, so they scale with the button.
     Mapbox's own stylesheet loads after ours, so its 29px wins on a tie:
     these need the extra class to beat it. */
  .mapboxgl-ctrl.mapboxgl-ctrl-group button {
    width: 40px;
    height: 40px;
    background-size: 20px 20px;
  }
  /* The style switcher sits with them and should match. */
  .map-style-ctl button { min-height: 40px; }
  /* Leaflet is the map served without a Mapbox token and draws its
     zoom buttons at 30px on touch. Its stylesheet loads after ours and
     would win a specificity tie, hence the id. */
  #map.leaflet-touch .leaflet-bar a { width: 40px; height: 40px; line-height: 40px; }

  /* The dot stays small; the area you press does not. */
  .carousel-dot, .sp-dots button { position: relative; }
  .carousel-dot::after, .sp-dots button::after {
    content: "";
    position: absolute;
    inset: -15px -9px;
  }

  /* Small print that is genuinely read rather than glanced at. */
  .fact-label { font-size: 12.5px; }
  .fleet-mock-foot { font-size: 12.5px; }
  .fleet-mock-stats .l { font-size: 12.5px; }
  /* On a phone there is no hover, so this hint is the only thing that
     says the boot can be dragged. It has to be readable. */
  .map-origin .grab-tag { font-size: 12.5px; }
  /* Three tabs across a phone: the height is what makes them hittable. */
  .rate-tab { min-height: 44px; }
  /* The sold-out flag under the listing H1, phone only: on a laptop
     the book card carries the word beside the photograph, but on a
     phone that card is three screens down. The template inlines
     display none so a laptop can never show it, which is why this
     needs the !important. The stone pill is drawn for the parchment
     page; on the charcoal head it needs porcelain to read. */
  p.head-sold { display: block !important; }
  .head-sold .pill {
    background: rgba(247, 243, 235, 0.16);
    color: var(--porcelain);
  }

  /* Behind a login. The header account chip, the tab rows on the host
     bookings and admin waitlist pages, and the admin activity feed were
     all drawn at mouse sizes, and they are on every page of the two
     dashboards, so they are the first thing a thumb meets. */
  .user-box { min-height: 44px; display: inline-flex; align-items: center; }
  .tab-row a { min-height: 44px; display: inline-flex; align-items: center; }
  .activity-row { min-height: 44px; align-items: center; }
  .act-time { font-size: 12.5px; }
  .data-table .pill, .admin-actions .pill { font-size: 12.5px; }
  /* A record's name in a table is the link to that record, so it is a
     control and not prose: it needs the height of one. */
  .data-table td a {
    display: inline-flex;
    align-items: center;
    min-height: 40px;
  }
  .type-tab { min-height: 44px; }
  /* Padding rather than flex, deliberately: making the summary a flex
     container turns "Several listings?" and the words after it into two
     flex items and eats the space between them. */
  .start-card summary { min-height: 44px; padding: 11px 0; }

  /* A table is a laptop shape. Seven columns across 390px either clip
     at the right edge or squeeze a title into a five-line column, and
     a sideways scroller inside a page that scrolls down is a thing
     nobody finds. So each row becomes a card, and each cell prints its
     column name beside its value: the same information read down the
     phone instead of across a desk.

     Only tables whose cells carry data-label transform. The rest are
     already two-column field lists and read correctly as they are. A
     browser without :has() keeps the scroller, which is what it has
     today, so there is nothing to fall back to. */
  .table-scroll:has(td[data-label]) { overflow-x: visible; }
  .data-table:has(td[data-label]),
  .data-table:has(td[data-label]) tbody { display: block; }
  .data-table:has(td[data-label]) tr:has(th) { display: none; }
  .data-table:has(td[data-label]) tr:has(td) {
    display: block;
    padding: 13px 14px;
    margin-bottom: 12px;
    border: 1px solid rgba(17, 19, 18, 0.14);
    border-radius: 4px;
  }
  .data-table td[data-label] {
    display: flex;
    gap: 16px;
    justify-content: space-between;
    align-items: baseline;
    text-align: right;
    padding: 7px 0;
    border-bottom: 0;
  }
  .data-table td[data-label]::before {
    content: attr(data-label);
    flex: 0 0 auto;
    text-align: left;
    font-size: 12px;
    font-weight: 700;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    color: var(--stone);
  }
  /* The first cell names the record, so it is the card's heading and a
     label on it would only repeat the column it obviously is. */
  .data-table tr > td[data-label]:first-child:not([colspan]) {
    display: block;
    text-align: left;
    padding: 0 0 10px;
    margin-bottom: 4px;
    font-size: 15.5px;
    border-bottom: 1px solid rgba(17, 19, 18, 0.1);
  }
  /* An empty label is the actions column, or a row that spans: neither
     wants a name printed next to it. */
  .data-table tr > td[data-label]:first-child::before,
  .data-table td[colspan]::before,
  .data-table td[data-label=""]::before { content: none; }
  .data-table td[colspan] { display: block; text-align: left; }
  /* The actions column is a row of 112px buttons, which is a laptop
     row: four of them are 460px wide. On a card they wrap and share
     the width instead. */
  .data-table td[data-label=""],
  .data-table td[data-label=""] .admin-actions {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    text-align: left;
    padding-top: 11px;
  }
  .data-table td[data-label=""] .btn-small,
  .data-table td[data-label=""] .more-menu,
  .data-table td[data-label=""] .inline-form { flex: 1 1 auto; }
  .data-table td[data-label=""] .inline-form .btn-small,
  .data-table td[data-label=""] .more-menu > summary { width: 100%; }
  /* A cell that holds controls rather than a value: the name goes above
     them on its own line, and they wrap underneath. */
  .data-table td[data-label]:has(.btn, button, .more-menu) {
    flex-wrap: wrap;
    justify-content: flex-start;
    text-align: left;
    padding-top: 11px;
  }
  .data-table td[data-label]:has(.btn, button, .more-menu)::before {
    flex: 1 0 100%;
    margin-bottom: 8px;
  }
  /* The More menu opens against the right edge of a laptop table; in a
     card it has the whole width. */
  .data-table .more-menu-items { right: auto; left: 0; min-width: 220px; }

  /* The bookings calendar is the one table that must stay a table: a
     week is a row of seven whatever the screen. Automatic layout let a
     driver's name widen its column until Sunday fell off the edge, so
     the columns are fixed at a seventh each and everything inside them
     wraps. */
  .cal-table { table-layout: fixed; }
  .cal-table th { font-size: 11.5px; padding: 7px 2px; }
  .cal-table td {
    height: 62px;
    padding: 4px 2px;
    font-size: 12.5px;
    overflow-wrap: break-word;
  }
  .cal-table .who { font-size: 12px; line-height: 1.25; margin-top: 2px; }
  /* A first name is all that fits in a 41px column and stays readable. */
  .cal-table .who-type { display: none; }

  /* A row of full size buttons at the foot of a dashboard sits side by
     side on a laptop and ends up ragged on a phone, each a different
     width depending on its label. Stacked and full width, they read as
     a list of things you can do. */
  .account-main :not(p):not(td) > .btn:not(.btn-small) {
    display: block;
    width: 100%;
    text-align: center;
  }
  .account-main :not(p):not(td) > .btn:not(.btn-small) + .btn:not(.btn-small) {
    margin-top: 10px;
  }

  /* The listing's book bar. Fixed to the foot of the screen, so the
     price and the way to act on it are never more than a thumb away.
     Hidden until its script has something real to put in it, and the
     script only fills it on a phone. */
  .book-bar {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 60;
    display: flex;
    align-items: center;
    gap: 14px;
    padding: 10px 16px;
    padding-bottom: calc(10px + env(safe-area-inset-bottom, 0px));
    background: var(--charcoal);
    border-top: 1px solid rgba(214, 183, 123, 0.35);
    /* Rises into place rather than appearing, the same move as the
       map's floating card, decelerating to a stop. Display none resets
       it, so it re-runs whenever the bar comes back. */
    animation: bar-rise 0.3s cubic-bezier(0.22, 1, 0.36, 1);
  }
  @keyframes bar-rise { from { transform: translateY(100%); } to { transform: none; } }
  @media (prefers-reduced-motion: reduce) {
    .book-bar { animation: none; }
  }
  .book-bar-price {
    flex: 1 1 auto;
    min-width: 0;
    color: var(--porcelain);
    line-height: 1.15;
  }
  .book-bar-price strong {
    display: block;
    font-family: var(--serif);
    font-size: 21px;
    font-weight: 400;
  }
  .book-bar-price span {
    display: block;
    font-size: 11.5px;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--brass);
    margin-top: 2px;
  }
  .book-bar .btn {
    flex: 0 0 auto;
    min-height: 46px;
    display: inline-flex;
    align-items: center;
    padding: 0 26px;
  }
  /* Room to scroll past the last line rather than under the bar. The
     bar's own padding grows by the home-indicator inset in the app
     shell, so the room underneath grows with it, or the page's last
     line sits permanently behind the bar on a notched phone. */
  body.has-book-bar { padding-bottom: calc(82px + env(safe-area-inset-bottom, 0px)); }

  /* Cards were given their breathing room in a three across grid on a
     laptop. Stacked one under another on a phone, the same padding
     turns three lines of text into half a screen and pushes everything
     below it down by pages. */
  /* viewport-fit=cover means the page paints under the rounded corners
     and the notch, so the sides have to be held clear of them or a
     landscape phone eats the first characters of every line. */
  body {
    padding-left: env(safe-area-inset-left, 0px);
    padding-right: env(safe-area-inset-right, 0px);
  }

  /* The page is parchment but both ends of it are charcoal, so the
     iOS rubber band opened a bare parchment gap above the header and
     below the footer: the app visibly ended at either end of every
     scroll. With the canvas behind the page charcoal, an overscroll
     reads as the header or the footer stretching, which is how a
     native scroll view behaves, and the bounce itself is kept. Screen
     only: at a paper width the phone rules apply too, and a charcoal
     canvas must not reach a printed statement. */
  @media screen {
    html { background: var(--charcoal); }
  }

  .card { padding: 22px 20px; }

  /* A tick box, a dropdown and the line of text beside them are one
     control, and the line is what a thumb aims at. */
  .checkbox-row label,
  label.checkbox-row,
  .form-row label:has(input[type="checkbox"]),
  .form-card label:has(input[type="checkbox"]) {
    display: flex;
    /* nowrap and 24px of gap are for a row of short feature boxes on a
       laptop; a sentence beside one tick box needs neither, and with
       them the box wrapped onto its own line above the words. */
    flex-wrap: nowrap;
    align-items: flex-start;
    gap: 9px;
    min-height: 44px;
  }
  label.checkbox-row input[type="checkbox"] { margin-top: 2px; flex: 0 0 auto; }
  .search-panel select { min-height: 40px; }
  .msg-meta { font-size: 12.5px; }
  .card h3, .card .card-h { font-size: 19px; margin-bottom: 9px; }
  .card .step-no { margin-bottom: 8px; }
  .section .sub { margin-bottom: 26px; font-size: 16px; }

  /* A listing card on an area page is a whole screen tall on a phone,
     because the photograph keeps the shape it has in a laptop grid. In
     a column you are scanning, that means comparing two spaces is a
     scroll each way. Side by side, three fit on the screen and every
     price sits in the same place down the page. The search results are
     already a compact row of their own, so they keep it. */
  .space-card:not(.space-row) { flex-direction: row; align-items: stretch; }
  .space-card:not(.space-row) .photo {
    flex: 0 0 124px;
    aspect-ratio: auto;
    align-self: stretch;
  }
  .space-card:not(.space-row) .photo svg,
  .space-card:not(.space-row) .photo img.logo-ph { width: 42px; }
  .space-card:not(.space-row) .body {
    flex: 1 1 auto;
    min-width: 0;
    padding: 14px 16px;
  }
  .space-card:not(.space-row) h3 { font-size: 16px; line-height: 1.25; }
  .space-card:not(.space-row) .meta { font-size: 12.5px; margin-bottom: 8px; }
  .space-card:not(.space-row) .price { font-size: 20px; }

  /* The one thing a form is for. On a laptop it sits at its label's
     width under a wide card; on a phone, where every field above it
     already fills the screen, anything narrower reads as secondary. */
  .form-card > .btn:not(.btn-small),
  .form-card > form > .btn:not(.btn-small) {
    display: block;
    width: 100%;
    text-align: center;
  }

  /* Four of the thirteen account tabs fit on the screen, so the strip
     scrolls. The fade at the edge is the only thing that says so. */
  .account-nav-card { position: relative; }
  .account-nav-card::after {
    content: "";
    position: absolute;
    top: 1px;
    right: 0;
    bottom: 1px;
    width: 26px;
    pointer-events: none;
    background: linear-gradient(to right,
                rgba(247, 243, 235, 0), var(--porcelain));
  }

  /* In the account areas the footer's four columns of marketing links
     are longer than the page they sit under, and the person reading
     came to do something, not to browse areas. The mark and the line
     stay so the page still ends somewhere. */
  .app-area .site-footer .cols > *:not(:first-child) { display: none; }
  .app-area .site-footer .cols { margin-bottom: 18px; }
  .app-area .site-footer { padding-bottom: 26px; }
  /* The pricing table's column widths are for a laptop grid. In a card
     they squeeze each number box to a couple of characters, so the box
     takes a fixed share of the row and the title takes the rest. */
  .price-table th, .price-table td, .price-table td:first-child { width: auto; }
  .price-table .price-box { flex: 0 0 145px; width: 145px; }

  /* Nothing-here rows are a sentence, not a card of fields. */
  .data-table td[colspan] { border-bottom: 0; }
  /* A heading between two card stacks has no top margin of its own: on
     a laptop the table below it carries the space, and a card stack
     does not. */
  .account-main .section h2 { margin-top: 28px; }
  .account-main .section > .wrap > h2:first-child { margin-top: 0; }
  /* The result card is deliberately compact on a phone, but 9.5px is
     past compact and into unreadable. A pill anywhere else is 11px,
     which is under the readable floor too: the payments page put one in
     a card and one in every row of a table, where it carries the whole
     status of somebody's money. Twelve everywhere. */
  .pill { font-size: 12px; }
  .space-row .pill { font-size: 12px; padding: 3px 8px; }
  /* A big search renders every result in one document: London is 1471
     cards, 18,700 nodes and a 221,000px page, all laid out and painted
     whether on screen or not. Every card is exactly 136px tall, so the
     off-screen ones can skip layout and paint entirely without moving a
     pixel: the intrinsic size below matches the fixed height, so the
     document height and every card's offset are unchanged to the
     sub-pixel, and the in-page re-sort and the pin-hover scroll measure
     the same boxes either way. Halves layout time on a phone load. */
  .space-row { content-visibility: auto; contain-intrinsic-size: auto 136px; }
  /* A chip and a row button are both things you press with a thumb. */
  .nearby-chip { min-height: 44px; display: inline-flex; align-items: center; }
  .btn-small { min-height: 40px; }
  .sv-pill { min-height: 40px; display: inline-flex; align-items: center; }
  /* Until Mapbox arrives, or when it cannot, offline in the app
     shell, the minimap is a bare parchment void with a pill floating
     in it. Charcoal underneath reads as a map about to happen, and
     the dark-v11 tiles fade in over the same tone instead of
     flashing dark over parchment. */
  #minimap { background: var(--charcoal); }
  /* The payments explainer is four cards side by side on a laptop and a
     single column on a phone: two columns at this width leaves each one
     about twenty characters wide. */
  .pay-grid { grid-template-columns: 1fr; gap: 14px; }
  /* The date filter is two fields and three buttons. Side by side in a
     flex row they each end up too narrow to tap, so the fields share a
     row and the buttons take one each below.
     minmax(0, 1fr), not 1fr: a track's default minimum is the content's
     min-content width, and an input[type=date] carries an intrinsic
     width of 180px on iOS. Two of those plus the gap made the row 370px
     inside a 318px column and pushed the whole page 16px sideways. Same
     trap as .start-card, and the fix is the same: let the track shrink
     below its content. */
  .filter-row {
    display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    gap: 10px;
  }
  .filter-row > div { min-width: 0; }
  .filter-row .btn { grid-column: span 2; }
  .filter-row input { width: 100%; min-width: 0; }
  /* A Stripe transfer id is 25 characters of no interest until something
     is wrong, so it must not set the width of a card. */
  .mono { font-size: 12px; }

  /* A press acknowledges the finger: the button gives a hair under it
     and returns on release. Touch has no hover, so this is the only
     feedback a tap gets. */
  @media (prefers-reduced-motion: no-preference) {
    .btn { transition: transform 0.12s ease; }
    .btn:active { transform: scale(0.98); }
  }

  /* --- The app-first layer (Henry, 2026-08-29, all phones) --------- */
  /* The bottom tab bar is the navigation; the header slims to the
     wordmark. Secondary links live in the footer and on Account. */
  #pw-tabbar {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 950;
    display: flex;
    background: var(--charcoal);
    border-top: 1px solid rgba(214, 183, 123, 0.35);
    padding-bottom: env(safe-area-inset-bottom, 0px);
  }
  #pw-tabbar a {
    flex: 1;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 3px;
    padding: 9px 0 7px;
    text-decoration: none;
    color: rgba(247, 243, 235, 0.55);
    font-family: var(--sans);
    font-size: 10.5px;
    letter-spacing: 0.02em;
  }
  #pw-tabbar a.active { color: var(--brass); }
  #pw-tabbar svg { width: 22px; height: 22px; }
  .site-header .my-storewelly, .site-header .burger { display: none; }
  /* Everything fixed to the foot stacks above the bar, and the page
     keeps clear of it. */
  body { padding-bottom: calc(64px + env(safe-area-inset-bottom, 0px)); }
  body.has-book-bar { padding-bottom: calc(146px + env(safe-area-inset-bottom, 0px)); }
  .book-bar { bottom: calc(64px + env(safe-area-inset-bottom, 0px)); padding-bottom: 10px; }
  .space-panel:not([hidden]) { bottom: calc(64px + env(safe-area-inset-bottom, 0px)); padding-bottom: 16px; }

  /* The calm home (option A, approved from the previews): a flat
     charcoal field, no film, no lede; the headline and the search card
     are the whole first screen. The loader in home.html is gated on
     the same width, so a phone never fetches either video encode. */
  .hero-video, .hero-shade { display: none; }
  .hero { background: var(--charcoal); }
  .hero .lede { display: none; }
  .hero-inner { padding: 56px 0 36px; }

  /* The app in the hero, on a phone: no picture (the picture source
     hands a phone a 1px gif, so nothing is fetched either) and the
     eyebrow, one line and the badge move under the search box, so the
     first screen grows by that and no more. One column, three rows. */
  .hero .wrap {
    grid-template-columns: minmax(0, 1fr);
    grid-template-areas: "copy" "search" "app";
    column-gap: 0;
  }
  .hero-app { padding: 0 0 18px; display: block; width: auto; }
  .hero-app .app-phone { display: none; }
  .hero-app-copy {
    max-width: none;
    text-align: left;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    column-gap: 16px;
    row-gap: 4px;
  }
  .hero-app-copy .eyebrow { flex: 1 0 100%; margin-bottom: 0; }
  .hero-app-copy p:not(.eyebrow) { flex: 1 1 12em; }
  .hero-app-copy .store-badge { margin-top: 0; }
  /* With the app block now the last thing in the hero, the panel's
     margin is the gap to it rather than to the parchment. */
  .hero .search-panel { margin-bottom: 18px; }

  /* The app section: a stack of cards, each a small screen beside its
     line, rather than three tall phones one under another. */
  .app-grid { grid-auto-flow: row; grid-auto-columns: auto; gap: 12px; max-width: none; }
  .app-card {
    display: flex;
    align-items: center;
    gap: 16px;
    padding: 12px 16px 12px 12px;
    border: 1px solid rgba(214, 183, 123, 0.3);
    border-radius: 4px;
    background: rgba(247, 243, 235, 0.04);
  }
  .app-card .app-phone {
    width: 96px;
    flex: none;
    margin: 0;
    padding: 4px;
    border-radius: 16px;
    box-shadow: 0 0 0 1px rgba(214, 183, 123, 0.45), 0 10px 24px rgba(0, 0, 0, 0.45);
  }
  .app-card .app-phone img { border-radius: 12px; }
  .app-card figcaption { text-align: left; margin: 0; max-width: none; font-size: 14.5px; }
  .app-cta { margin-top: 28px; padding-top: 24px; }
  /* A thumb needs the badge at 44px wherever it is, the footer too.
     The footer's chip rule above outranks the laptop badge rule, so the
     badge is taken back out of it here: it is a badge, not a chip. */
  .store-badge img, .site-footer .foot-app .store-badge img { height: 44px; }
  .site-footer .cols .foot-app a.store-badge { display: inline-block; padding: 0; border: 0; min-height: 0; }
  .foot-app { margin-top: 16px; }
  .cancellation-link {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
    max-width: 100%;
    padding: 8px 0;
  }
}

/* Touch feel in the app shell. Everything above answers a mouse with
   :hover, which a finger never fires, so in the app a press changed
   nothing on screen until the page did and taps felt swallowed. Where
   hover does not exist, the press itself paints the answer the hover
   would have given. Inert on laptops: hover: none never matches a
   mouse. */
@media (hover: none) {
  .btn:active { background: var(--brass-deep); }
  .btn-outline:active { background: var(--brass); color: var(--charcoal); }
  .btn-dark:active { background: var(--green-bright); }
  .btn-danger:active { background: var(--terracotta); color: var(--porcelain); }
  .btn-stone:active { background: var(--charcoal); color: var(--brass); }
  .btn-green:active { background: var(--charcoal); color: var(--brass); }
  .btn-terracotta:active { background: var(--charcoal); color: var(--brass); }
  .my-storewelly:active { background: var(--porcelain); }
  .user-box:active { background: var(--brass-deep); }
  .filter-btn:active { background: var(--brass); color: var(--charcoal); }
  .rate-pill:active { background: var(--brass); color: var(--charcoal); }
  .type-tab:active { border-color: var(--brass); }
  .space-card:active { border-color: var(--brass); }
  .area-link:active { background: var(--porcelain); border-color: var(--brass); color: var(--green); }
  .account-nav a:active { background: var(--parchment); color: var(--green); }
  .account-nav-out button:active { background: var(--parchment); }
  .more-menu-items a:active,
  .more-menu-items button:active { background: var(--parchment); color: var(--green); }
  .site-footer .cols a:not(.wordmark):not(.welly-footer-link):active { border-color: var(--brass); }
  .sv-pill:active { background: var(--green); color: var(--porcelain); }
  .carousel-btn:active { background: var(--green); }
  .space-panel .sp-close:active { background: var(--charcoal); color: var(--brass); }
  .space-panel .sp-arrow:active { background: var(--green); }
  .map-pill:active { background: var(--green); z-index: 4; }
  .map-pill:active::after { border-top-color: var(--green); }
  .suggest-item:active { background: var(--parchment); color: var(--green); }

  /* A long press on a control is a missed tap, not an attempt to copy
     its label: selecting the word Book and raising the copy sheet is
     the browser showing through the app. Chrome only; prose and data
     stay selectable. */
  .btn, button, summary, .pill, .rate-pill, .map-pill, .type-tab,
  .burger, .view-toggle, .tab-row a, .account-nav a, .wordmark,
  .site-footer .cols a, .filter-btn, .nearby-chip {
    -webkit-user-select: none;
    user-select: none;
  }
  .burger, .view-toggle, summary, .map-pill { -webkit-touch-callout: none; }
}

/* Storage imagery within the unchanged ParkWelly layout. */
.storage-preview-screen{position:relative;background:var(--porcelain);border-radius:26px;overflow:hidden;color:var(--charcoal);height:470px}.storage-island{position:absolute;left:50%;top:9px;transform:translateX(-50%);width:67px;height:18px;border-radius:20px;background:#111312;z-index:3}.storage-preview-brand{display:flex;align-items:center;gap:6px;padding:38px 13px 12px;font:500 20px/1 var(--serif)}.storage-preview-brand img{width:24px;height:24px;border-radius:5px}.storage-preview-brand>span>span{color:#96733c}.storage-preview-photo{height:190px;position:relative;overflow:hidden}.storage-preview-photo>img{height:100%;width:100%;object-fit:cover;border-radius:0}.storage-preview-photo>span{position:absolute;left:11px;bottom:10px;background:#111312dd;color:#f7f3eb;border-radius:3px;padding:4px 7px;font-size:8px;letter-spacing:.03em}.storage-preview-body{padding:15px 13px}.storage-preview-body small{font-size:9px;color:var(--stone)}.storage-preview-body h2{font-size:23px;line-height:1.14;margin:8px 0 14px;color:var(--charcoal)}.storage-preview-tabs{display:flex;gap:4px;border-bottom:1px solid #d7cfbe;padding-bottom:9px}.storage-preview-tabs button{padding:7px 7px;border:0;border-radius:3px;background:transparent;color:#526150;font:500 9px/1.2 var(--sans);cursor:pointer}.storage-preview-tabs button[aria-pressed=true]{background:#163f32;color:#f7f3eb}.storage-preview-caption{font-size:10px;color:#64675f;margin:10px 0!important}.storage-preview-body>a{display:block;background:#d6b77b;padding:10px 7px;text-align:center;color:#111312;font-size:11px;font-weight:650;text-decoration:none;border-radius:3px}.storage-preview-body>a:focus-visible,.storage-preview-tabs button:focus-visible{outline:2px solid #9b7135;outline-offset:3px}.store-scenes{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:24px;margin-top:34px}.store-scenes>a{position:relative;display:block;height:420px;border-radius:5px;overflow:hidden;color:#f7f3eb}.store-scenes>a:after{content:'';position:absolute;inset:35% 0 0;background:linear-gradient(transparent,#071b12d9)}.store-scenes img{width:100%;height:100%;object-fit:cover;transition:transform 1s cubic-bezier(.2,.7,.3,1)}.store-scenes>a:hover img{transform:scale(1.045)}.store-scenes>a>span{position:absolute;left:25px;right:20px;bottom:29px;z-index:1}.store-scenes small{display:block;font-size:12px;line-height:1.7;margin-bottom:12px;color:#e2dac9}.store-scenes strong{font:450 36px/1.1 var(--serif);letter-spacing:-.03em}.store-image-note{font-size:12px;line-height:1.7;color:#bbbfb2;margin-top:21px}.store-legal{font-size:12px;line-height:1.7;color:#afb5a9;max-width:650px;margin-top:15px}.store-reveal{opacity:0;transform:translateY(20px);transition:opacity .7s ease,transform .7s cubic-bezier(.2,.7,.3,1)}.store-visible{opacity:1;transform:none}.calc label{display:block;font-size:14px;margin:20px 0 10px;color:#d6b77b}.calc input[type=number]{width:100%;padding:14px;border:1px solid #776d56;border-radius:3px;background:#f7f3eb;color:#111312;font:400 20px var(--serif)}.calc input[type=range]{width:100%;accent-color:#d6b77b}.store-launch-note{font-size:13px;line-height:1.7;border-top:1px solid #9c8b6333;padding-top:15px;margin-top:22px}
@media(max-width:1100px){.storage-preview-screen{height:427px}.storage-preview-photo{height:159px}.storage-preview-body h2{font-size:20px}.storage-preview-body{padding:11px}.storage-preview-tabs button{font-size:8px;padding:7px 5px}.store-scenes>a{height:370px}.store-scenes strong{font-size:31px}}
@media(max-width:880px){.hero-app-copy .btn{display:none}.store-scenes{grid-template-columns:1fr;gap:22px}.store-scenes>a{height:380px}.store-scenes strong{font-size:36px}.store-scenes>a>span{left:27px;bottom:28px}.store-image-note{font-size:12px}.store-legal{font-size:12px}.hero-app-copy p{font-size:14px}.hero-app-copy p br{display:none}.hero-app-copy p br:after{content:' '}.hero-app-copy .eyebrow{font-size:11px}.store-scenes small{font-size:13px}}
@media(prefers-reduced-motion:reduce){.store-reveal{opacity:1;transform:none}.store-scenes img{transition:none}.store-scenes>a:hover img{transform:none}}
.storage-preview-photo{height:170px}.storage-preview-body{padding:13px;line-height:1.4}.storage-preview-body small{display:block}.storage-preview-body h2{font-size:20px;line-height:1.08;letter-spacing:-.03em;margin:8px 0 12px}.storage-preview-body>a{padding:8px 7px}.storage-preview-caption{margin:8px 0!important}@media(max-width:1100px){.storage-preview-photo{height:145px}.storage-preview-body h2{font-size:19px}.storage-preview-body{padding:11px}}
@media(max-width:880px){.hero:before{content:'';position:absolute;inset:0;background:linear-gradient(180deg,#11131294,#111312dc 56%,#111312ef),url('/static/img/storage/storage-hero.webp') center 30%/cover;z-index:0;pointer-events:none}.hero .hero-shade{display:none}}
