/*
  Styling for the public booking pages and the member-facing /dashboard
  (they share this one file). Design tokens (--ink, --cream, etc.) live in
  brand.css, loaded alongside this file in every layout; see that file's
  comment for why.
*/
* { box-sizing: border-box; }

body {
  margin: 0;
  background: var(--cream);
  color: var(--ink);
  font-family: var(--font-sans);
  -webkit-font-smoothing: antialiased;
}

.public-header {
  max-width: 480px;
  margin: 0 auto;
  padding: 2rem 1.5rem 0;
  text-align: center;
}

.public-logo-link {
  display: inline-block;
}

.public-logo {
  height: 28px;
  width: auto;
}

.public-booking {
  max-width: 480px;
  margin: 0 auto;
  padding: 3rem 1.5rem 5rem;
}

.public-booking h1 {
  font-family: var(--font-serif);
  font-size: clamp(2rem, 5vw, 2.75rem);
  font-weight: 400;
  line-height: 1.15;
  margin-bottom: 1rem;
}

.public-booking .lead {
  font-size: 1.0625rem;
  line-height: 1.6;
  color: rgba(29, 34, 28, 0.7);
  margin-bottom: 2rem;
}

/* Pages that opt in via content_for(:body_class, "has-side-image") (and a
   content_for(:side_image) block, rendered by the layout as a sibling of
   .page-left) get a full-bleed split screen: a one-third left column
   (logo, content, legal footer, vertically distributed) and a two-thirds
   image column stretching edge-to-edge. Everything else keeps the plain
   single-column layout. .page-left/.side-image only take on this
   treatment inside the .has-side-image scope. */
body.has-side-image {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 2fr);
  height: 100vh;
}

/* height (not min-height) + overflow-y:auto so this column scrolls on its
   own when content is taller than the viewport, while the image column
   stays pinned at a fixed 100vh via the grid row's height.
   position:relative matters too: it makes this column the containing block
   for absolutely-positioned descendants (e.g. .visually-hidden labels low
   in a long form). Without it they're positioned against the page itself,
   escape this column's overflow clipping, and stretch the document taller
   than the viewport, so the whole page (image included) scrolls. */
body.has-side-image .page-left {
  position: relative;
  display: flex;
  flex-direction: column;
  height: 100vh;
  overflow-y: auto;
  padding: 0 2rem;
}

/* The column itself is usually narrower than the default 480px content
   width, so without this the form would just fill it edge-to-edge rather
   than reading as centered within the column. The header shares this same
   centered-block treatment so the (left-aligned) logo lines up with the
   form/legal text's own left edge, rather than the column's outer edge. */
/* width:100% matters here. Without it, .public-header's box would
   shrink-wrap around just the logo (flex cross-axis auto-margins override
   stretch when content is narrower than the container), leaving it a
   different width/position than .public-booking, whose wider form content
   naturally fills out to max-width on its own. */
body.has-side-image .public-header,
body.has-side-image .public-booking,
body.has-side-image .public-footer {
  width: 100%;
  max-width: 420px;
}

/* Vertically centers the main content between the logo and the legal
   footer, rather than it sitting flush under the logo. */
body.has-side-image .public-booking {
  flex: 1 0 auto;
  display: flex;
  flex-direction: column;
  justify-content: center;
}

/* This layout is more height-constrained than the default single-column
   pages get (full viewport, no page scroll expected), so the generous
   padding/margins that work fine on a normal scrolling page are trimmed
   here specifically. Top/bottom split unevenly on purpose:
   less above the title (close to the logo) and less below the button
   (close to the legal text) than the default single-column spacing. */
body.has-side-image .public-header {
  padding-top: 1.25rem;
  text-align: left;
}
body.has-side-image .public-logo { height: 60px; }
body.has-side-image .public-booking { padding: 0.75rem 1.5rem; }
body.has-side-image .public-booking .lead { margin-bottom: 1.5rem; }
body.has-side-image .field { margin-bottom: 1rem; }
body.has-side-image .public-footer { padding: 1rem 1.5rem 1.5rem; }

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

@media (max-width: 860px) {
  body.has-side-image {
    display: block;
    height: auto;
  }

  body.has-side-image .page-left {
    display: block;
    height: auto;
    overflow-y: visible;
  }

  body.has-side-image .public-booking {
    display: block;
  }

  .side-image {
    display: none;
  }
}

.field {
  display: flex;
  flex-direction: column;
  gap: 0.375rem;
  margin-bottom: 1.25rem;
}

.field label {
  font-size: 0.78rem;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: rgba(29, 34, 28, 0.65);
}

.field input[type="text"],
.field input[type="email"],
.field input[type="tel"],
.field input[type="number"],
.field input[type="date"],
.field input[type="datetime-local"],
.field input[type="password"],
.field select {
  width: 100%;
  min-width: 0;
  box-sizing: border-box;
  background: #fff;
  border: 1px solid rgba(29, 34, 28, 0.2);
  border-radius: 6px;
  padding: 0.75rem 1rem;
  font-family: var(--font-sans);
  font-size: 1rem;
  color: var(--ink);
}

/* Native <select> chrome renders at a different height than a text input
   even with identical padding/border — appearance: none strips that out
   so it's box-model-identical to every other field, with our own chevron
   standing in for the native arrow this removes. */
.field select {
  appearance: none;
  -webkit-appearance: none;
  -moz-appearance: none;
  padding-right: 2.5rem;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath d='M2.5 4.5L6 8l3.5-3.5' stroke='%231d221c' stroke-opacity='0.55' stroke-width='1.5' fill='none' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 1rem center;
}

/* Mobile Safari gives input[type="date"] its own internal minimum content
   width (enough for the full locale date + calendar glyph) that wins over
   width: 100% on a narrow phone viewport, so the field renders wider than
   its siblings and pokes past the edge of the form. appearance: none opts
   it out of that native layout — box-model-identical to the text fields —
   while tapping it still opens the native date picker on iOS/Android. */
.field input[type="date"],
.field input[type="datetime-local"] {
  appearance: none;
  -webkit-appearance: none;
  -moz-appearance: none;
}

.field input:focus,
.field select:focus {
  outline: none;
  border-color: var(--sage);
  box-shadow: 0 0 0 3px rgba(124, 154, 128, 0.25);
}

.duration-prices {
  list-style: none;
  padding: 0;
  margin: 0 0 2rem;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  font-size: 0.9375rem;
}

.duration-prices li {
  display: flex;
  justify-content: space-between;
  border-bottom: 1px solid rgba(29, 34, 28, 0.1);
  padding-bottom: 0.5rem;
}

.field-errors {
  color: var(--danger);
  font-size: 0.875rem;
  margin-top: 0.25rem;
}

.field-hint {
  font-size: 0.8125rem;
  color: rgba(29, 34, 28, 0.55);
  margin: 0;
}

/* .text-link's colour and hover underline, but not its fixed font-size:
   a link mid-sentence in a hint keeps the hint's size. Colour and
   decoration only, so a .text-link placed in a hint keeps its own size. */
.field-hint a { color: var(--moss); text-decoration: none; }
.field-hint a:hover { text-decoration: underline; }

.field-checkbox {
  display: flex;
  align-items: flex-start;
  gap: 0.5rem;
  margin-bottom: 1.25rem;
  font-size: 0.9375rem;
}

/* Our own `display: flex` above otherwise wins over the browser's default
   [hidden] { display: none }. Author styles always beat the UA
   stylesheet, regardless of selector specificity or source order, so the
   `hidden` attribute (used by early_performance_gate_controller.js) would
   silently do nothing without this. */
.field-checkbox[hidden] {
  display: none;
}

.field-checkbox input[type="checkbox"] {
  margin-top: 0.2em;
  flex-shrink: 0;
}

/* .time-slots and its variants now live in brand.css, shared with
   admin.css (the admin booking forms' live-availability pickers). */

.terms-privacy-note {
  font-size: 0.9375rem;
  margin: 0 0 1rem;
}

.public-booking h2 {
  font-family: var(--font-serif);
  font-size: 1.375rem;
  font-weight: 400;
  margin: 2rem 0 1rem;
}

.terms-content h2 {
  font-size: 1.0625rem;
  margin: 1.75rem 0 0.5rem;
}

.terms-content ul {
  margin: 0;
  padding-left: 1.25rem;
}

.terms-content li {
  font-size: 0.9375rem;
  line-height: 1.6;
  color: rgba(29, 34, 28, 0.8);
  margin-bottom: 0.375rem;
}

.terms-footer {
  margin-top: 2rem;
  padding-top: 1.5rem;
  border-top: 1px solid rgba(29, 34, 28, 0.1);
  font-size: 0.875rem;
  font-style: italic;
  color: rgba(29, 34, 28, 0.6);
}

.text-link {
  color: var(--moss);
  font-size: 0.9375rem;
  font-weight: 600;
  text-decoration: none;
}

.text-link:hover { text-decoration: underline; }

.devise-links {
  margin-top: 1.5rem;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

.devise-links p { margin: 0; }

/* .status-badge and .notice/.alert now live in brand.css, shared with
   admin.css. Both load it already. */

.error-summary {
  background: rgba(168, 50, 50, 0.08);
  border: 1px solid rgba(168, 50, 50, 0.3);
  border-radius: 6px;
  padding: 1rem 1.25rem;
  margin-bottom: 1.5rem;
  color: var(--danger);
  font-size: 0.9375rem;
}

.error-summary p:first-child { margin-top: 0; }
.error-summary p + p { margin-top: 0.375rem; }

/* A proper welcome for founders rather than a small status pill, same
   tinted-box language as .error-summary above, in copper instead of
   danger red. */
/* Corners and padding match .perks-panel and the dashboard cards, so the
   two panels read as one family at different volumes: a quiet faded
   thank-you here, the solid call to action there. */
.founder-panel {
  background: rgba(168, 109, 71, 0.08);
  border: 1px solid rgba(168, 109, 71, 0.3);
  border-radius: var(--radius-lg);
  padding: 1.25rem 1.5rem;
  margin-bottom: 1.5rem;
  color: var(--copper);
  font-size: 0.9375rem;
}

/* Same serif heading as the dashboard cards (.dashboard-card h2), in the
   panel's copper. */
.founder-panel h2 {
  color: var(--copper);
}

.founder-panel p {
  margin: 0;
}

/* The dashboard home's pointer to member perks: solid moss, so it stands
   apart from the faded-moss .next-steps-panel. Cream on moss is about
   5.6:1, so the text stays readable; solid sage would be too pale. */
.perks-panel {
  background: var(--moss);
  color: var(--cream);
  border-radius: var(--radius-lg);
  padding: 1.25rem 1.5rem;
  margin-bottom: 1.5rem;
}

.perks-panel h2 {
  color: var(--cream);
}

.perks-panel p {
  margin: 0;
  font-size: 0.9375rem;
}

/* A right-aligned "View details ->" style text link, the same look as a
   perk tile's (.perk-tile-more). Cream on the perks panel, where moss
   would vanish into the background. */
.link-more {
  display: block;
  margin-top: 0.75rem;
  text-align: right;
  color: var(--moss);
  font-size: 0.9375rem;
  font-weight: 600;
  text-decoration: none;
}

.link-more:hover {
  text-decoration: underline;
}

.perks-panel .link-more {
  color: var(--cream);
}

/* A pending membership's "What happens next" (dashboard/memberships/
   _next_steps): the same tinted-box language as .founder-panel, in moss,
   since it's guidance rather than a celebration. */
.next-steps-panel {
  background: rgba(var(--moss-rgb), 0.08);
  border: 1px solid rgba(var(--moss-rgb), 0.3);
  border-radius: var(--radius-sm);
  padding: 1rem 1.25rem;
  margin-bottom: 1.5rem;
  font-size: 0.9375rem;
}

.next-steps-panel strong {
  display: block;
  margin-bottom: 0.25rem;
  color: var(--moss);
  font-size: 1rem;
}

.next-steps-panel p {
  margin: 0.5rem 0 0;
}

/* Plain navigation, not an action — kept visually quieter than the .btn
   family (no fill, no border) so it reads as "go back" rather than
   competing with the page's actual buttons. Same rule as admin.css's
   .back-link. */
.back-link {
  display: inline-block;
  margin-bottom: 0.75rem;
  color: var(--sage);
  text-decoration: none;
  font-size: 0.875rem;
}

.back-link:hover { text-decoration: underline; }

/* button_to renders a block-level <form> by default, which stacks
   multiple actions vertically with no gap between them — same fix as
   admin.css. */
.button_to { display: inline-block; }

.btn-primary {
  display: inline-block;
  width: 100%;
  padding: 0.9375rem 1.5rem;
  background: var(--moss);
  color: #fff;
  border: none;
  border-radius: 6px;
  font-family: var(--font-sans);
  font-size: 0.9375rem;
  font-weight: 600;
  text-align: center;
  text-decoration: none;
  cursor: pointer;
  transition: background 0.18s;
}

.btn-primary:hover { background: var(--moss-hover); }

.btn-primary:disabled {
  background: rgba(var(--moss-rgb), 0.35);
  cursor: not-allowed;
}

.btn-primary:disabled:hover { background: rgba(var(--moss-rgb), 0.35); }

/* .btn-primary is full-width by default, correct for an actual form
   submit (e.g. "Book trial day," "Sign up"), wrong for an inline CTA link
   sitting in running text (e.g. "Add an ad hoc visit"). Additive modifier,
   doesn't touch the shared default. (admin.css's .btn-primary is
   auto-width by default instead — deliberate, see the comment there.) */
.btn-primary.btn-auto {
  display: inline-block;
  width: auto;
}

.btn {
  display: inline-block;
  width: auto;
  padding: 0.5rem 1rem;
  background: #fff;
  color: var(--ink);
  border: 1px solid rgba(29, 34, 28, 0.2);
  border-radius: 6px;
  font-family: var(--font-sans);
  font-size: 0.875rem;
  font-weight: 600;
  text-align: center;
  text-decoration: none;
  cursor: pointer;
}

.btn:hover { border-color: var(--sage); }

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

.btn-danger:hover { background: var(--danger); color: #fff; }

.btn-warning {
  background: var(--warning-bg);
  color: var(--warning);
  border-color: var(--warning);
}

.btn-warning:hover { background: var(--warning); color: #fff; }

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

.turnstile-widget { margin-bottom: 1.25rem; }

.confirmation-card {
  text-align: center;
  padding: 2.5rem 2rem;
  background: #fff;
  border: 1px solid rgba(29, 34, 28, 0.1);
  border-radius: var(--radius-lg);
}

.public-footer {
  max-width: 720px;
  margin: 0 auto;
  padding: 0 1.5rem 3rem;
  text-align: center;
}

.public-footer-legal {
  font-size: 0.75rem;
  line-height: 1.5;
  color: rgba(29, 34, 28, 0.45);
  margin: 0;
}

.confirmation-note {
  font-size: 0.875rem;
  color: rgba(29, 34, 28, 0.6);
  margin-top: 0.75rem;
}

.confirmation-icon {
  width: 3rem;
  height: 3rem;
  margin: 0 auto 1rem;
  background: var(--sage);
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  color: #fff;
  font-size: 1.25rem;
  font-weight: 700;
}

/* White card, same visual language as .dashboard-card, rather than a solid
   fill — reads as "the first card on the page" instead of a bar bolted on
   top, consistent with the rest of the dashboard's light/editorial look. */
.dashboard-nav {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 1.25rem;
  max-width: 720px;
  margin: 1.5rem auto 0;
  padding: 0.875rem 1.5rem;
  background: #fff;
  border: 1px solid rgba(29, 34, 28, 0.1);
  border-radius: var(--radius-lg);
}

.dashboard-nav a {
  color: var(--ink);
  text-decoration: none;
  font-size: 0.9375rem;
  font-weight: 600;
}

.dashboard-nav a:hover {
  color: var(--sage);
}

.dashboard-nav a.current {
  color: var(--moss);
}

.dashboard-nav-home svg {
  display: block;
  width: 1.25rem;
  height: 1.25rem;
}

.dashboard-nav-account {
  position: relative;
  margin-left: auto;
}

.dashboard-nav-account summary {
  display: flex;
  align-items: center;
  gap: 0.25rem;
  cursor: pointer;
  list-style: none;
  color: var(--ink);
  font-size: 0.9375rem;
  font-weight: 600;
}

.dashboard-nav-account summary::-webkit-details-marker {
  display: none;
}

.dashboard-nav-account summary:hover {
  color: var(--sage);
}

.dashboard-nav-account-chevron {
  width: 1rem;
  height: 1rem;
  transition: transform 0.15s ease;
}

.dashboard-nav-account[open] .dashboard-nav-account-chevron {
  transform: rotate(180deg);
}

.dashboard-nav-account-menu {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0.5rem;
}

/* The floating panel chrome only applies to the copy nested inside the
   <details> (the desktop dropdown) — the always-visible mobile copy below
   reuses .dashboard-nav-account-menu purely for its link layout/typography. */
.dashboard-nav-account > .dashboard-nav-account-menu {
  position: absolute;
  top: 100%;
  right: 0;
  margin-top: 0.5rem;
  background: #fff;
  border: 1px solid rgba(29, 34, 28, 0.1);
  border-radius: var(--radius-sm);
  padding: 0.75rem;
  min-width: 160px;
  box-shadow: 0 4px 12px rgba(29, 34, 28, 0.08);
}

/* Sign out is a button_to form, not a link, but should read as one of the
   nav's plain text links rather than a bordered pill. */
.dashboard-nav-account-menu a,
.dashboard-nav-account-menu button {
  background: none;
  border: none;
  margin: 0;
  padding: 0;
  font: inherit;
  color: var(--ink);
  font-size: 0.9375rem;
  font-weight: 600;
  text-decoration: none;
  cursor: pointer;
}

.dashboard-nav-account-menu a:hover,
.dashboard-nav-account-menu button:hover {
  color: var(--sage);
}

/* The always-visible mobile stand-in for the Account dropdown (see the
   comment on .dashboard-nav-account-mobile below for why a real dropdown
   won't do here). Hidden on desktop; swapped in below 720px. */
.dashboard-nav-account-mobile {
  display: none;
}

/* Below this, the nav card's own edges start touching the viewport edges
   (it has no outer margin once the viewport is narrower than its 720px
   max-width) — stack every item vertically rather than wrapping run-on
   groups. The Account dropdown is swapped for plain always-visible links:
   Chromium keeps a closed <details>'s content unpainted even when its
   `display` is forced open via author CSS (the closed state is enforced
   below the CSS box model, not just via a plain `display: none` a media
   query could override), so a real dropdown can't be forced into an
   always-open mobile state — hence the separate .dashboard-nav-account-mobile
   block with its own copy of the links instead. */
@media (max-width: 720px) {
  .dashboard-nav {
    flex-direction: column;
    align-items: center;
  }

  .dashboard-nav-account {
    display: none;
  }

  .dashboard-nav-account-mobile {
    display: flex;
    align-items: center;
    gap: 1.25rem;
  }
}

.dashboard-card {
  background: #fff;
  border: 1px solid rgba(29, 34, 28, 0.1);
  border-radius: var(--radius-lg);
  padding: 1.5rem;
  margin-bottom: 1.5rem;
}

.dashboard-card h2,
.founder-panel h2,
.perks-panel h2 {
  font-family: var(--font-serif);
  font-size: 1.375rem;
  font-weight: 400;
  margin: 0 0 1rem;
}

/* The tinted panels' headings sit tight above a single line of text. */
.founder-panel h2,
.perks-panel h2 {
  margin-bottom: 0.25rem;
}

.dashboard-card table {
  width: 100%;
  border-collapse: collapse;
}

.dashboard-card th, .dashboard-card td {
  text-align: left;
  padding: 0.5rem 0;
  border-bottom: 1px solid rgba(29, 34, 28, 0.08);
  font-size: 0.9375rem;
}

.dashboard-card th {
  color: rgba(29, 34, 28, 0.55);
  font-weight: 600;
  width: 40%;
}

/* "Need to change..." reads too close to the rows above it with the
   default zero top margin .field-hint uses elsewhere (e.g. directly under
   a form input, where that's correct). This scoped rule only affects a
   hint immediately following a stacked-row list inside a dashboard-card. */
.dashboard-card .stacked-row + .field-hint {
  margin-top: 0.75rem;
}

/* One shared row shape for every dashboard-card list (memberships,
   hot-desk visits, invoices, upcoming bookings): a bold title line, an
   optional muted secondary line, a badge+amount meta line (badge always
   first), then any action button(s) on their own line — all of it always
   stacked (rather than only wrapping when it doesn't fit) so every row's
   shape stays predictable regardless of how long its content is, and
   every list in the dashboard reads the same way at a glance. */
.stacked-row {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0.5rem;
  padding: 0.75rem 0;
  border-bottom: 1px solid rgba(29, 34, 28, 0.08);
  font-size: 0.9375rem;
}

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

.stacked-row-secondary {
  color: rgba(29, 34, 28, 0.55);
  font-size: 0.875rem;
}

.stacked-row-meta {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.5rem 0.75rem;
}

/* Action button(s) (View, Download PDF, Reschedule/Cancel) sit on their
   own line like everything else in .stacked-row, but pulled to the right
   edge (align-self, since the row itself is a column flex container) to
   read as the row's action rather than another line of information. */
.stacked-row-actions {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.5rem 0.75rem;
  align-self: flex-end;
}

/* Member perks (dashboard/perks): one dashboard-card per business, its
   logo -- or initials in the same footprint when there's no logo yet --
   beside the name, with the offer itself picked out in moss so it's what
   the eye lands on. */
.perk-header {
  display: flex;
  align-items: center;
  gap: 1rem;
  margin-bottom: 1rem;
}

.perk-header h2 {
  margin: 0;
}

/* The perk's category (see MemberPerks::CATEGORIES) under its name: a
   small moss Heroicon and label, quiet beside the name and offer. */
.perk-category {
  display: inline-flex;
  align-items: center;
  gap: 0.375rem;
  margin-top: 0.25rem;
  color: var(--moss);
  font-size: 0.8125rem;
  font-weight: 600;
}

.perk-category-icon {
  width: 1rem;
  height: 1rem;
  flex-shrink: 0;
}

/* Holds the logo, or the initials standing in for it (see the perk-logo
   Stimulus controller), so the name beside it doesn't shift either way. */
.perk-logo-slot {
  display: flex;
  flex-shrink: 0;
}

/* Every logo is the same height, and as wide as its shape needs up to a
   landscape limit: a square mark (Midlands Podcast Studio's) sits in the same 4rem
   square as the initials fallback, so its name lines up with theirs and
   its rounded corners land on the image itself, while a wide full logo
   still has up to 6rem to stay legible. */
.perk-logo {
  flex-shrink: 0;
  width: auto;
  max-width: 6rem;
  height: 4rem;
  border-radius: var(--radius-sm);
  object-fit: contain;
  object-position: left center;
}

.perk-monogram[hidden] {
  display: none;
}

.perk-monogram {
  width: 4rem;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(var(--moss-rgb), 0.12);
  color: var(--moss);
  font-family: var(--font-serif);
  font-size: 1.375rem;
  font-weight: 600;
}

.perk-offer {
  background: rgba(var(--moss-rgb), 0.08);
  border-left: 3px solid var(--moss);
  border-radius: var(--radius-sm);
  padding: 0.75rem 1rem;
  color: var(--moss);
  font-weight: 600;
}

.perk-offer p {
  margin: 0;
}

.perk-offer p + p {
  margin-top: 0.5rem;
}

/* On the perks index each perk is a short tile linking to its own page
   (dashboard/perks/show), so the card itself is the link. */
.perk-tile {
  display: block;
  color: inherit;
  text-decoration: none;
  transition: border-color 0.15s ease, box-shadow 0.15s ease;
}

.perk-tile:hover,
.perk-tile:focus-visible {
  border-color: var(--moss);
  box-shadow: 0 2px 8px rgba(var(--moss-rgb), 0.12);
}

.perk-tile .perk-offer {
  margin-bottom: 0;
}

.perk-tile .perk-offer-warning {
  margin: 0.5rem 0 0;
}

.perk-tile-more {
  display: block;
  margin-top: 0.75rem;
  text-align: right;
  color: var(--moss);
  font-size: 0.9375rem;
  font-weight: 600;
}

.perk-tile:hover .perk-tile-more {
  text-decoration: underline;
}

.perk-card h3 {
  font-size: 0.9375rem;
  margin: 1.25rem 0 0.25rem;
}

.perk-card h3 + p {
  margin-top: 0;
}

.perk-card .perk-terms {
  margin-top: 1rem;
}

.perk-terms ul {
  margin: 0.25rem 0 0;
  padding-left: 1.25rem;
}

.perk-terms li + li {
  margin-top: 0.25rem;
}

/* A web address in perk text (see PerksHelper#perk_text) wraps at the
   <wbr> after each slash; break-word only splits a segment mid-word if
   even that alone is wider than the screen. */
.perk-link {
  color: var(--moss);
  font-weight: 600;
  text-decoration: none;
  overflow-wrap: break-word;
}

.perk-link:hover { text-decoration: underline; }
