:root {
  --brand-mint: #38ef7d;
  --brand-mint-active: #2fd06c;
  --brand-mint-soft: #e3faed;
  --brand-teal: #11998e;
  --brand-teal-active: #0c7269;
  --brand-ink: #16281f;

  /* Garden accents for small decorative touches (the home page category chips) - always used as a
     tint behind body-coloured text or as a solid decoration, never as a text colour. */
  --garden-leaf: #38ef7d;
  --garden-teal: #11998e;
  --garden-sun: #f6c445;
  --garden-blossom: #f28cb1;
  --garden-lavender: #a78bfa;
  --garden-terracotta: #e8875b;

  /* A starter radius/shadow scale: border-radius and box-shadow values were previously all ad hoc
     literals, several sitting in the same visual role (e.g. card elevation) with no evident reason
     to differ. Matched to the most common existing values rather than inventing new ones, and
     applied to the clearest duplicate/near-duplicate cases below as a verified zero-or-near-zero
     visual diff - the rest of the historical one-off values are left for future opportunistic
     cleanup rather than a single big-bang rewrite. */
  --radius-sm: .5rem;
  --radius-md: .85rem;
  --radius-lg: 1rem;
  --shadow-sm: 0 8px 24px rgba(15, 23, 42, .06);
  --shadow-md: 0 14px 32px rgba(15, 23, 42, .1);
  --shadow-lg: 0 1.5rem 4rem rgba(15, 23, 42, .22);
}

html {
  font-size: 14px;
}

@media (min-width: 768px) {
  html {
    font-size: 16px;
  }
}

/* Keyboard-only ring (not on mouse click/tap) in the brand teal, matching the same :focus-visible
   convention the admin area already uses (its own ring color, since admin intentionally keeps its
   own slate/green palette - see docs/style-guide.md §1/§2). .form-control keeps plain :focus (not
   gated to keyboard), same as every text input site-wide including admin's own .form-control:focus
   rule below - a user needs to see which field they clicked into regardless of input method. */
.btn:focus-visible, .btn-link.nav-link:focus-visible, .form-check-input:focus-visible, .form-control:focus {
  box-shadow: 0 0 0 0.1rem var(--bs-body-bg), 0 0 0 0.25rem var(--brand-teal);
}

/* Off-screen until keyboard-focused, on both the public site and admin - lets a keyboard/screen-
   reader user jump straight to <main id="main-content"> instead of tabbing through the full nav
   (public: logo + 5 links + search; admin: brand + sub-nav dropdowns) on every single page. */
.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 2000;
  padding: .5rem 1rem;
  background: var(--brand-teal);
  color: #fff;
  text-decoration: none;
  border-radius: 0 0 var(--radius-sm) 0;
}

.skip-link:focus {
  left: 0;
}

/* Narrower reading width for text-heavy public sections (About, Contact, Policy) -
   the original site's .small-container, ported per docs/style-guide.md
   §4. Centers inside the already-centered/padded .container it's nested in. */
.small-container {
  max-width: 1080px;
  margin-inline: auto;
}

/* De-emphasised paragraph copy inside those same sections, matching the original site's
   .par-font p (docs/style-guide.md §2) - a theme-aware muted tone rather than the original's
   literal #666767, so it stays legible in dark mode too (see site.css's dark-mode guidance). */
.par-font p {
  color: var(--bs-secondary-color);
}

html {
  position: relative;
  min-height: 100%;
}

body {
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  margin-bottom: 0;
}

main[role="main"] {
  flex: 1 0 auto;
}

/* Brand header: a fixed mint-to-teal gradient that stays the same in light and dark mode
   (it doesn't read any --bs-* theme variable), matching the original site's signature band.
   Plain white nav text/icons (not navbar-dark's default 55%-opacity white) for readability
   against the gradient. */
.site-header {
  background: linear-gradient(to right, var(--brand-mint) 0%, var(--brand-teal) 100%);
  --bs-navbar-color: #fff;
  --bs-navbar-hover-color: #fff;
  --bs-navbar-active-color: #fff;
  --bs-navbar-brand-color: #fff;
  --bs-navbar-brand-hover-color: #fff;
  /* White passes comfortably against the teal end of the gradient but is thin (~1.6:1) against
     the mint end - text-shadow is inherited, so this one declaration covers every nav link, the
     brand mark, and icon glyphs without needing a rule per element. */
  text-shadow: 0 1px 2px rgba(0, 0, 0, .35);
  /* Sticky so the nav and search stay in reach while scrolling the catalogue. Bootstrap's
     sticky-top z-index keeps it above page content but below dropdowns/modals. */
  position: sticky;
  top: 0;
  z-index: 1020;
}

/* Collapsed-nav height (py-3 + the 48px-tall logo; py-lg-4 on desktop). In-page anchors such as
   /#about and /#contact scroll this far short so their headings aren't hidden under the sticky header. */
:root {
  --site-header-height: 5rem;
}

@media (min-width: 992px) {
  :root {
    --site-header-height: 6rem;
  }
}

html {
  scroll-padding-top: var(--site-header-height);
}

/* Mobile: the expanded menu/search lives inside the sticky header, so let it scroll on short
   (e.g. landscape phone) screens instead of running off the bottom of the viewport. */
@media (max-width: 991.98px) {
  .site-header .navbar-collapse,
  .site-header #mobileSearch {
    max-height: calc(100vh - var(--site-header-height));
    overflow-y: auto;
  }
}

/* Footer stays a fixed dark grey in both light and dark mode, matching the original
   site's footer, rather than following the public-site theme toggle. */
.site-footer {
  background-color: #333333;
  color: #f2f5ec;
}

.site-footer a,
.site-footer .btn-link {
  color: inherit;
}

.site-footer a:hover,
.site-footer .btn-link:hover {
  color: #fff;
}

/* A brand-coloured CTA button, fixed across themes like the header gradient above.
   Mint by default, darkening to teal on hover/active - the same behaviour as the
   original site's .btn. Used in place of .btn-dark, whose fill is the same near-black
   shade as Bootstrap's dark-mode page background and was nearly invisible when the
   theme toggle was dark. Dark text on the mint fill (white was too low-contrast to
   read); once it darkens to teal on hover/active, white text works fine again. */
.btn-brand {
  --bs-btn-color: #16281f;
  --bs-btn-bg: var(--brand-mint);
  --bs-btn-border-color: var(--brand-mint);
  --bs-btn-hover-color: #fff;
  --bs-btn-hover-bg: var(--brand-teal);
  --bs-btn-hover-border-color: var(--brand-teal);
  --bs-btn-active-color: #fff;
  --bs-btn-active-bg: var(--brand-teal-active);
  --bs-btn-active-border-color: var(--brand-teal-active);
  --bs-btn-disabled-color: #16281f;
  --bs-btn-disabled-bg: var(--brand-mint);
  --bs-btn-disabled-border-color: var(--brand-mint);
}

/* Public-site section heading: default heading text, left-aligned, with a short mint-to-teal
   underline bar below it (matching the original site's .title::after mark - a small bar, not a
   full-width rule). text-align is forced so a heading inside a centred block still lines up
   with the rest of the site's headings. */
.heading-gradient {
  text-align: start;
}

.heading-gradient::after {
  content: "";
  display: block;
  width: 4rem;
  height: 0.3rem;
  margin-top: 0.5rem;
  margin-inline: 0;
  border-radius: 999px;
  background: linear-gradient(to right, var(--brand-mint) 0%, var(--brand-teal) 100%);
}

/* Home page banner: the same mint-to-teal gradient as .site-header, bled full-width past
   its container (the standard 100vw/negative-margin break-out) regardless of how deep it's
   nested, matching the original site's promo band. */
.home-banner {
  background: linear-gradient(to right, var(--brand-mint) 0%, var(--brand-teal) 100%);
  width: 100vw;
  margin-left: calc(50% - 50vw);
  margin-right: calc(50% - 50vw);
  padding-block: 3rem;
}

@media (min-width: 992px) {
  .home-banner {
    padding-block: 4rem;
  }
}

/* Fixed dark text (not Bootstrap's theme-aware body color), same as .btn-brand's own text
   below: in dark mode the default body text is near-white, which would otherwise repeat the
   .site-header contrast problem against this same mint/teal gradient. */
.home-banner h2,
.home-banner p {
  color: #16281f;
}

/* Banner copy: a pill badge, a larger title, a description clamped to four lines (the full text
   stays in the DOM; the product page has it in full) and a prominent price. */
.home-banner-badge {
  display: inline-block;
  padding: .25rem .75rem;
  border-radius: 999px;
  background: rgba(255, 255, 255, .35);
  font-size: .75rem;
  font-weight: 700;
  letter-spacing: .08em;
  text-transform: uppercase;
}

.home-banner-title {
  font-size: clamp(1.75rem, 3vw, 2.5rem);
  font-weight: 700;
}

.home-banner-desc {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 4;
  line-clamp: 4;
  overflow: hidden;
  font-size: 1.05rem;
  line-height: 1.6;
}

.home-banner-price {
  font-size: 1.5rem;
  font-weight: 700;
}

.home-banner .product-media {
  border-radius: var(--radius-sm);
  box-shadow: 0 .75rem 2rem rgba(0, 0, 0, .25);
  overflow: hidden;
}

/* A light CTA for the banner above: .btn-brand's mint fill would nearly disappear against
   the gradient it now sits on, so this pairs a pale button with the dark body text used
   elsewhere on that background. */
.home-banner .btn {
  --bs-btn-color: #16281f;
  --bs-btn-bg: #fff;
  --bs-btn-border-color: #fff;
  --bs-btn-hover-color: #16281f;
  --bs-btn-hover-bg: var(--brand-mint);
  --bs-btn-hover-border-color: var(--brand-mint);
  --bs-btn-active-color: #16281f;
  --bs-btn-active-bg: var(--brand-mint-active);
  --bs-btn-active-border-color: var(--brand-mint-active);
}

/* FAQ card in the home page's Contact Us section: a brand-mint tint a step stronger than the
   .home-hero band it sits on. It's mixed into the theme's own body background (not the fixed
   --brand-mint-soft), so in dark mode it stays a dark card. A fixed light fill left the "FAQs"
   heading light-on-light, and the dark accordion items glared against it. */
.faq-section {
  background-color: color-mix(in srgb, var(--brand-mint) 22%, var(--bs-body-bg));
}

/* The nav/footer About and Contact links are in-page anchors on the home page (/#about, /#contact),
   so glide to them rather than jumping - unless the visitor has asked for reduced motion. */
@media (prefers-reduced-motion: no-preference) {
  html {
    scroll-behavior: smooth;
  }
}

/* The home page's About Us (top) and Contact Us (bottom) heroes: a full-width band tinted with the
   brand mint. color-mix against the theme's own body background (rather than the fixed
   --brand-mint-soft) keeps it a soft tint in dark mode too, so body text keeps its normal theme colour. */
.home-hero {
  --home-hero-bg: color-mix(in srgb, var(--brand-mint) 12%, var(--bs-body-bg));
  background: var(--home-hero-bg);
  padding-block: 3rem;
  scroll-margin-top: 1rem;
}

@media (min-width: 992px) {
  .home-hero {
    padding-block: 5rem;
  }
}

/* The Contact band closes the home page, so it runs straight into the footer: drop the footer's
   usual mt-5 gap there (other pages keep it). */
main:has(.home-hero--contact) + .footer {
  margin-top: 0 !important;
}

/* A thin brand gradient rule along the top edge separates the Contact band from the sections above it. */
.home-hero--contact {
  border-top: .3rem solid;
  border-image: linear-gradient(to right, var(--brand-mint) 0%, var(--brand-teal) 100%) 1;
}

.home-hero-eyebrow {
  margin-bottom: .5rem;
  color: var(--brand-teal);
  font-size: .85rem;
  font-weight: 700;
  letter-spacing: .08em;
  text-transform: uppercase;
}

[data-bs-theme="dark"] .home-hero-eyebrow {
  color: var(--brand-mint);
}

.home-hero-media {
  overflow: hidden;
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-md);
}

.about-gallery-pause {
  position: absolute;
  right: 0.75rem;
  bottom: 0.75rem;
  z-index: 3;
}

.filter-count-badge {
  background-color: var(--brand-teal);
  color: #fff;
}

.home-hero-media .about-gallery-img {
  border-radius: 0;
}

/* The About hero's story cards (history, plants, landscaping). */
.home-feature {
  padding: 1.5rem;
  border-radius: var(--radius-md);
  background: var(--bs-body-bg);
  box-shadow: var(--shadow-sm);
}

.home-feature-icon,
.home-contact-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  border-radius: 50%;
  background: linear-gradient(135deg, var(--brand-mint) 0%, var(--brand-teal) 100%);
  color: #fff;
}

.home-feature-icon {
  width: 3rem;
  height: 3rem;
  font-size: 1.35rem;
}

/* Phones: each About feature card is a collapsed heading row (icon, title, chevron) that opens its text. */
.home-feature-toggle {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  width: 100%;
  padding: 0;
  border: 0;
  background: none;
  color: inherit;
  font: inherit;
  text-align: start;
}

.home-feature-toggle .home-feature-icon {
  width: 2.5rem;
  height: 2.5rem;
  font-size: 1.1rem;
}

.home-feature-chevron {
  transition: transform 0.2s ease;
}

.home-feature-toggle:not(.collapsed) .home-feature-chevron {
  transform: rotate(180deg);
}

@media (max-width: 767.98px) {
  .home-feature {
    padding: 1rem 1.25rem;
  }
}

/* md and up: the cards are laid out side by side with room to spare, so the text is always shown, the icon
   sits above the title as before, and the toggle is inert (site.js also disables it for keyboard users). */
@media (min-width: 768px) {
  .home-feature-toggle {
    flex-direction: column;
    align-items: flex-start;
    gap: 1rem;
    cursor: default;
    pointer-events: none;
  }

  .home-feature-toggle .home-feature-icon {
    width: 3rem;
    height: 3rem;
    font-size: 1.35rem;
  }

  .home-feature-chevron {
    display: none;
  }

  .home-feature-body.collapse:not(.show),
  .home-feature-body.collapsing {
    display: block;
    height: auto !important;
  }
}

.home-contact-icon {
  width: 2.5rem;
  height: 2.5rem;
  font-size: 1.1rem;
}

.home-whatsapp {
  max-width: 220px;
}

/* Post cards: the excerpt is clamped to a few lines, with the full text one click away on the post's own page. */
.home-post-excerpt {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 4;
  line-clamp: 4;
  overflow: hidden;
}

.home-post-more {
  color: var(--brand-teal);
  font-weight: 600;
  text-decoration: none;
}

.home-post-more:hover {
  color: var(--brand-teal-active);
}

/* A post's own page (Posts/Details.cshtml): a readable line length, with images kept inside it. */
.post-article {
  max-width: 48rem;
}

.post-article .post-gallery-trigger {
  padding: 0;
  border: 0;
  background: none;
}

.post-article-cover {
  width: 100%;
  max-height: 32rem;
  object-fit: cover;
  border-radius: .5rem;
}

.post-article-photo {
  width: 100%;
  aspect-ratio: 1;
  object-fit: cover;
  border-radius: .5rem;
}

.post-body {
  overflow-wrap: anywhere;
}

.post-body img {
  max-width: 100%;
  height: auto;
}

.post-body > :last-child {
  margin-bottom: 0;
}

.post-body a,
.post-pager a {
  color: var(--brand-teal);
}

.post-body a:hover,
.post-pager a:hover {
  color: var(--brand-teal-active);
}

/* Modals opened from the home page (the map) get the brand gradient along their top edge. */
.home-modal {
  overflow: hidden;
  border: 0;
  padding-top: .3rem;
  /* A background layer rather than border-image, which would square off the modal's rounded corners. */
  background:
    linear-gradient(to right, var(--brand-mint) 0%, var(--brand-teal) 100%) top / 100% .3rem no-repeat,
    var(--bs-modal-bg);
}

.home-map {
  display: block;
  width: 100%;
  height: min(450px, 60vh);
  border: 0;
}

body.admin-dashboard-page {
  background: #f3f5f9;
  color: #1f2a37;
}

body.admin-dashboard-page .admin-topbar {
  background: #23252d;
  color: #f8fafc;
  box-shadow: 0 1px 0 rgba(255, 255, 255, 0.06);
  position: sticky;
  top: 0;
  z-index: 20;
}

body.admin-dashboard-page .admin-topbar__inner {
  min-height: 4rem;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
}

body.admin-dashboard-page .admin-brand {
  display: inline-flex;
  align-items: center;
  gap: .75rem;
  color: inherit;
  text-decoration: none;
  font-weight: 700;
  white-space: nowrap;
}

body.admin-dashboard-page .admin-brand__logo {
  width: 2rem;
  height: 2rem;
  object-fit: contain;
  border-radius: .35rem;
  background: rgba(255, 255, 255, 0.92);
}

body.admin-dashboard-page .admin-brand__title {
  font-size: 1rem;
}

body.admin-dashboard-page .admin-topbar__timestamp {
  color: #cbd5e1;
  font-weight: 600;
  font-size: .95rem;
  flex: 1 1 auto;
  text-align: center;
}

body.admin-dashboard-page .admin-topbar__nav {
  display: inline-flex;
  align-items: center;
  gap: 1rem;
  flex-wrap: wrap;
  justify-content: flex-end;
}

body.admin-dashboard-page .admin-topbar__nav a,
body.admin-dashboard-page .admin-signout-link {
  color: #cbd5e1;
  text-decoration: none;
  font-size: .95rem;
  font-weight: 600;
}

body.admin-dashboard-page .admin-topbar__nav a:hover,
body.admin-dashboard-page .admin-signout-link:hover {
  color: #ffffff;
}

body.admin-dashboard-page .admin-signout-form {
  margin: 0;
}

body.admin-dashboard-page .admin-signout-link {
  background: transparent;
  border: 0;
  padding: 0;
}

body.admin-dashboard-page .admin-subnav {
  background: #2d2f38;
  border-top: 1px solid rgba(255, 255, 255, 0.06);
}

body.admin-dashboard-page .admin-subnav__list {
  display: flex;
  align-items: center;
  gap: 1.5rem;
  list-style: none;
  margin: 0;
  padding: .6rem 0;
  flex-wrap: wrap;
}

body.admin-dashboard-page .admin-subnav__item {
  position: relative;
}

body.admin-dashboard-page .admin-subnav__link {
  background: transparent;
  border: 0;
  padding: 0;
  color: #cbd5e1;
  font-size: .85rem;
  font-weight: 600;
  text-decoration: none;
  cursor: pointer;
}

body.admin-dashboard-page .admin-subnav__link:hover,
body.admin-dashboard-page .admin-subnav__link:focus-visible,
body.admin-dashboard-page .admin-subnav__link.is-active {
  color: #ffffff;
}

body.admin-dashboard-page .admin-dashboard-main {
  flex: 1 0 auto;
}

body.admin-dashboard-page .card-surface {
  background: rgba(255, 255, 255, 0.92);
  border: 1px solid rgba(15, 23, 42, 0.06);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
}

body.admin-dashboard-page .admin-users-page {
  max-width: 118rem;
  margin-inline: auto;
}

body.admin-dashboard-page .admin-breadcrumb {
  --bs-breadcrumb-divider: ">";
}

body.admin-dashboard-page .admin-breadcrumb .breadcrumb-item,
body.admin-dashboard-page .admin-breadcrumb a {
  color: #64748b;
  font-size: .78rem;
  font-weight: 600;
  text-decoration: none;
}

body.admin-dashboard-page .admin-breadcrumb a:hover,
body.admin-dashboard-page .admin-breadcrumb a:focus-visible {
  color: #166534;
  text-decoration: underline;
}

body.admin-dashboard-page .admin-page-heading {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 1.5rem;
}

body.admin-dashboard-page .admin-page-actions {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: .65rem;
  flex-wrap: wrap;
}

body.admin-dashboard-page .admin-eyebrow {
  color: #64748b;
  font-size: .7rem;
  font-weight: 800;
  letter-spacing: .08em;
  text-transform: uppercase;
}

body.admin-dashboard-page .admin-page-title {
  color: #0f172a;
  font-size: clamp(1.7rem, 4vw, 2.25rem);
  font-weight: 800;
}

body.admin-dashboard-page .admin-page-subtitle {
  color: #64748b;
  font-size: .95rem;
}

body.admin-dashboard-page .admin-status-alert {
  align-items: center;
  display: flex;
  justify-content: space-between;
  margin-bottom: 1rem;
}

body.admin-dashboard-page .admin-form-section-title {
  border-bottom: 1px solid rgba(15, 23, 42, .08);
  color: #334155;
  font-size: .75rem;
  font-weight: 800;
  letter-spacing: .08em;
  margin: .35rem 0 .1rem;
  padding-bottom: .5rem;
  text-transform: uppercase;
}

body.admin-dashboard-page .admin-form-section-title:not(:first-child) {
  margin-top: .8rem;
}

body.admin-dashboard-page .form-text {
  color: #64748b;
  font-size: .75rem;
}

body.admin-dashboard-page .form-check-input:disabled {
  cursor: not-allowed;
  opacity: .75;
}

body.admin-dashboard-page .admin-page-actions .btn,
body.admin-dashboard-page .admin-users-table .btn,
body.admin-dashboard-page .admin-products-table .btn,
body.admin-dashboard-page .admin-posts-table .btn,
body.admin-dashboard-page .admin-categories-table .btn,
body.admin-dashboard-page .modal-footer .btn {
  min-height: 2.5rem;
}

body.admin-dashboard-page .btn:focus-visible,
body.admin-dashboard-page a:focus-visible,
body.admin-dashboard-page input:focus-visible,
body.admin-dashboard-page .form-check-input:focus-visible {
  box-shadow: 0 0 0 .22rem rgba(47, 143, 87, .25);
  outline: 2px solid transparent;
  outline-offset: 2px;
}

body.admin-dashboard-page .admin-stat-card,
body.admin-dashboard-page .admin-users-card,
body.admin-dashboard-page .admin-products-card,
body.admin-dashboard-page .admin-posts-card,
body.admin-dashboard-page .admin-categories-card,
body.admin-dashboard-page .admin-users-page .card {
  border: 1px solid rgba(15, 23, 42, .08);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-sm) !important;
}

body.admin-dashboard-page .admin-stat-card .card-body {
  padding: 1rem 1.15rem;
}

body.admin-dashboard-page .admin-stat-card .display-6 {
  color: #0f172a;
  font-size: clamp(1.7rem, 3vw, 2.25rem);
  line-height: 1.15;
}

body.admin-dashboard-page .admin-modal {
  border: 0;
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-lg);
}

body.admin-dashboard-page .admin-modal .modal-header,
body.admin-dashboard-page .admin-modal .modal-footer {
  border-color: rgba(15, 23, 42, .08);
  padding: 1.15rem 1.35rem;
}

body.admin-dashboard-page .admin-modal .modal-body {
  padding: 1.35rem;
}

body.admin-dashboard-page .admin-modal .form-label {
  color: #334155;
  font-size: .82rem;
  font-weight: 700;
}

body.admin-dashboard-page .form-label.required::after {
  color: #dc3545;
  content: " *";
}

body.admin-dashboard-page .admin-modal .form-control,
body.admin-dashboard-page .admin-users-page .form-control {
  border-color: #dbe2ea;
  border-radius: .55rem;
  min-height: 2.65rem;
}

body.admin-dashboard-page .admin-modal .form-control:focus,
body.admin-dashboard-page .admin-users-page .form-control:focus {
  border-color: #2f8f57;
  box-shadow: 0 0 0 .2rem rgba(47, 143, 87, .14);
}

body.admin-dashboard-page .admin-users-card .card-header,
body.admin-dashboard-page .admin-products-card .card-header,
body.admin-dashboard-page .admin-posts-card .card-header,
body.admin-dashboard-page .admin-categories-card .card-header {
  padding: 1rem 1.15rem;
}

body.admin-dashboard-page .admin-users-table,
body.admin-dashboard-page .admin-products-table,
body.admin-dashboard-page .admin-posts-table,
body.admin-dashboard-page .admin-categories-table {
  min-width: 47rem;
}

body.admin-dashboard-page .admin-users-table th,
body.admin-dashboard-page .admin-products-table th,
body.admin-dashboard-page .admin-posts-table th,
body.admin-dashboard-page .admin-categories-table th {
  background: #f8fafc;
  color: #64748b;
  font-size: .7rem;
  font-weight: 800;
  letter-spacing: .06em;
  text-transform: uppercase;
  white-space: nowrap;
}

/* Click-to-sort headings (admin.js initializeSortableTables) */
body.admin-dashboard-page th[aria-sort] .admin-sort-btn {
  background: none;
  border: 0;
  padding: 0;
  margin: 0;
  font: inherit;
  letter-spacing: inherit;
  text-transform: inherit;
  color: inherit;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: .35rem;
}

body.admin-dashboard-page th[aria-sort] .admin-sort-btn:focus-visible {
  outline: 2px solid var(--bs-success, #198754);
  outline-offset: 3px;
  border-radius: .25rem;
}

body.admin-dashboard-page th[aria-sort] .admin-sort-icon {
  opacity: .35;
  font-size: .75rem;
}

body.admin-dashboard-page th[aria-sort] .admin-sort-icon::before { content: "\F127"; } /* bi-arrow-down-up */
body.admin-dashboard-page th[aria-sort="ascending"] .admin-sort-icon::before { content: "\F145"; } /* bi-arrow-up-short */
body.admin-dashboard-page th[aria-sort="descending"] .admin-sort-icon::before { content: "\F128"; } /* bi-arrow-down-short */
body.admin-dashboard-page th[aria-sort="ascending"] .admin-sort-icon,
body.admin-dashboard-page th[aria-sort="descending"] .admin-sort-icon,
body.admin-dashboard-page th[aria-sort] .admin-sort-btn:hover .admin-sort-icon {
  opacity: 1;
}

body.admin-dashboard-page .admin-users-table td,
body.admin-dashboard-page .admin-users-table th,
body.admin-dashboard-page .admin-products-table td,
body.admin-dashboard-page .admin-products-table th,
body.admin-dashboard-page .admin-posts-table td,
body.admin-dashboard-page .admin-posts-table th,
body.admin-dashboard-page .admin-categories-table td,
body.admin-dashboard-page .admin-categories-table th {
  padding: .9rem 1rem;
}

body.admin-dashboard-page .admin-users-table tbody tr:hover,
body.admin-dashboard-page .admin-products-table tbody tr:hover,
body.admin-dashboard-page .admin-posts-table tbody tr:hover,
body.admin-dashboard-page .admin-categories-table tbody tr:hover {
  background: #f8fafc;
}

[data-bs-theme="dark"] body.admin-dashboard-page {
  background: #111827;
  color: #e5e7eb;
}

[data-bs-theme="dark"] body.admin-dashboard-page .card-surface {
  background: #1f2937;
  border-color: #374151;
}

[data-bs-theme="dark"] body.admin-dashboard-page .action-card {
  background: #1f2937;
  border-color: #374151;
}

[data-bs-theme="dark"] body.admin-dashboard-page .action-card:hover,
[data-bs-theme="dark"] body.admin-dashboard-page .action-card:focus-visible,
[data-bs-theme="dark"] body.admin-dashboard-page .action-card:active {
  background: #273244;
}

[data-bs-theme="dark"] body.admin-dashboard-page .admin-breadcrumb .breadcrumb-item,
[data-bs-theme="dark"] body.admin-dashboard-page .admin-breadcrumb a,
[data-bs-theme="dark"] body.admin-dashboard-page .admin-eyebrow,
[data-bs-theme="dark"] body.admin-dashboard-page .admin-page-subtitle,
[data-bs-theme="dark"] body.admin-dashboard-page .form-text {
  color: #9ca3af;
}

[data-bs-theme="dark"] body.admin-dashboard-page .admin-page-title,
[data-bs-theme="dark"] body.admin-dashboard-page .admin-stat-card .display-6 {
  color: #f9fafb;
}

[data-bs-theme="dark"] body.admin-dashboard-page .admin-form-section-title,
[data-bs-theme="dark"] body.admin-dashboard-page .admin-modal .form-label {
  color: #d1d5db;
}

[data-bs-theme="dark"] body.admin-dashboard-page .admin-form-section-title,
[data-bs-theme="dark"] body.admin-dashboard-page .admin-modal .modal-header,
[data-bs-theme="dark"] body.admin-dashboard-page .admin-modal .modal-footer,
[data-bs-theme="dark"] body.admin-dashboard-page .admin-stat-card,
[data-bs-theme="dark"] body.admin-dashboard-page .admin-users-card,
[data-bs-theme="dark"] body.admin-dashboard-page .admin-products-card,
[data-bs-theme="dark"] body.admin-dashboard-page .admin-posts-card,
[data-bs-theme="dark"] body.admin-dashboard-page .admin-categories-card,
[data-bs-theme="dark"] body.admin-dashboard-page .admin-users-page .card {
  border-color: #374151;
}

[data-bs-theme="dark"] body.admin-dashboard-page .admin-modal .form-control,
[data-bs-theme="dark"] body.admin-dashboard-page .admin-users-page .form-control {
  border-color: #4b5563;
}

[data-bs-theme="dark"] body.admin-dashboard-page .admin-users-table th,
[data-bs-theme="dark"] body.admin-dashboard-page .admin-products-table th,
[data-bs-theme="dark"] body.admin-dashboard-page .admin-posts-table th,
[data-bs-theme="dark"] body.admin-dashboard-page .admin-categories-table th,
[data-bs-theme="dark"] body.admin-dashboard-page .admin-users-table tbody tr:hover,
[data-bs-theme="dark"] body.admin-dashboard-page .admin-products-table tbody tr:hover,
[data-bs-theme="dark"] body.admin-dashboard-page .admin-posts-table tbody tr:hover,
[data-bs-theme="dark"] body.admin-dashboard-page .admin-categories-table tbody tr:hover {
  background: #273244;
}

[data-bs-theme="dark"] body.admin-dashboard-page .admin-users-table th,
[data-bs-theme="dark"] body.admin-dashboard-page .admin-products-table th,
[data-bs-theme="dark"] body.admin-dashboard-page .admin-posts-table th,
[data-bs-theme="dark"] body.admin-dashboard-page .admin-categories-table th {
  color: #cbd5e1;
}

.password-field {
  position: relative;
}

.password-field .form-control {
  padding-right: 3rem;
}

.password-toggle {
  position: absolute;
  top: 50%;
  right: .45rem;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.2rem;
  height: 2.2rem;
  padding: 0;
  transform: translateY(-50%);
  color: var(--bs-secondary-color);
  background: transparent;
  border: 0;
  border-radius: .4rem;
}

.password-toggle:hover,
.password-toggle:focus-visible {
  color: #166534;
  background: rgba(34, 197, 94, .1);
  outline: none;
}

[data-bs-theme="dark"] .password-toggle:hover,
[data-bs-theme="dark"] .password-toggle:focus-visible {
  color: #4ade80;
  background: rgba(34, 197, 94, .18);
}

.cookie-banner {
  position: fixed;
  left: 1rem;
  right: 1rem;
  bottom: 1rem;
  z-index: 1080;
  max-width: 42rem;
  margin-inline: auto;
  padding: 1rem 1.25rem;
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: .75rem;
  font-size: .9rem;
}

.cookie-banner[hidden] {
  display: none;
}

@media (min-width: 576px) {
  .cookie-banner {
    flex-direction: row;
    align-items: center;
    gap: 1rem;
  }
}

.theme-toggle {
  width: 2.5rem;
  height: 2.5rem;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  border-radius: 50%;
}

.password-toggle svg {
  width: 1.15rem;
  height: 1.15rem;
  fill: none;
  stroke: currentColor;
  stroke-linecap: round;
  stroke-linejoin: round;
  stroke-width: 1.8;
}

@media (max-width: 767.98px) {
  body.admin-dashboard-page .admin-topbar__inner {
    min-height: 3.5rem;
  }

  body.admin-dashboard-page .admin-brand__title {
    font-size: .82rem;
  }

  body.admin-dashboard-page .admin-topbar__timestamp {
    display: none;
  }

  body.admin-dashboard-page .admin-page-heading {
    align-items: stretch;
    flex-direction: column;
    gap: 1rem;
  }

  body.admin-dashboard-page .admin-page-actions {
    justify-content: stretch;
  }

  body.admin-dashboard-page .admin-page-actions .btn {
    flex: 1 1 10rem;
  }

  body.admin-dashboard-page .admin-stat-grid {
    row-gap: .75rem;
    display: none;
  }

  body.admin-dashboard-page .admin-stat-card .card-body {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 1rem;
  }

  body.admin-dashboard-page .admin-stat-card .display-6 {
    margin: 0;
  }

  body.admin-dashboard-page .admin-modal .modal-dialog {
    margin: .75rem;
  }

  body.admin-dashboard-page .admin-modal .modal-body,
  body.admin-dashboard-page .admin-modal .modal-header,
  body.admin-dashboard-page .admin-modal .modal-footer {
    padding: 1rem;
  }

  body.admin-dashboard-page .admin-users-card .card-header,
  body.admin-dashboard-page .admin-products-card .card-header,
  body.admin-dashboard-page .admin-posts-card .card-header,
  body.admin-dashboard-page .admin-categories-card .card-header {
    align-items: flex-start !important;
    flex-direction: column;
  }

  body.admin-dashboard-page .admin-users-table td,
  body.admin-dashboard-page .admin-users-table th,
  body.admin-dashboard-page .admin-products-table td,
  body.admin-dashboard-page .admin-products-table th,
  body.admin-dashboard-page .admin-posts-table td,
  body.admin-dashboard-page .admin-posts-table th,
  body.admin-dashboard-page .admin-categories-table td,
  body.admin-dashboard-page .admin-categories-table th {
    padding: .75rem .8rem;
  }
}

body.admin-dashboard-page .dashboard {
  max-width: 72rem;
  margin-inline: auto;
}

/* The hero keeps fixed brand colours (like the site banner and the desktop app's dashboard), so it looks
   the same in light and dark mode. */
body.admin-dashboard-page .dashboard-hero {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 1rem;
  margin-bottom: 1.75rem;
  padding: 1.5rem 1.75rem;
  border-radius: .75rem;
  background: linear-gradient(135deg, #0b5f58 0%, var(--brand-teal) 100%);
}

body.admin-dashboard-page .dashboard-greeting__text {
  min-width: 0;
}

body.admin-dashboard-page .dashboard-avatar {
  width: 2.75rem;
  height: 2.75rem;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  border-radius: 50%;
  background: var(--brand-mint);
  color: #0b3d39;
  font-weight: 800;
}

body.admin-dashboard-page .dashboard-title {
  font-size: clamp(1.25rem, 3.5vw, 1.75rem);
  font-weight: 600;
  color: #fff;
  overflow-wrap: anywhere;
}

body.admin-dashboard-page .dashboard-subtitle {
  color: #cff5ee;
}

body.admin-dashboard-page .dashboard-role {
  display: inline-block;
  vertical-align: middle;
  margin-left: .4rem;
  padding: .1rem .65rem;
  border-radius: 1rem;
  background: var(--brand-mint);
  color: #0b3d39;
  font-size: .75rem;
  font-weight: 600;
}

/* At-a-glance figures on the right of the hero. */
body.admin-dashboard-page .dashboard-stats {
  display: flex;
  flex-wrap: wrap;
  gap: .75rem;
  margin: 0 0 0 auto;
  padding: 0;
  list-style: none;
}

body.admin-dashboard-page .dashboard-stat {
  display: flex;
  flex-direction: column;
  min-width: 6rem;
  padding: .6rem 1rem;
  border: 1px solid rgba(255, 255, 255, .2);
  border-radius: .65rem;
  background: rgba(255, 255, 255, .15);
}

body.admin-dashboard-page .dashboard-stat__value {
  color: #fff;
  font-size: 1.5rem;
  font-weight: 600;
  line-height: 1.2;
}

body.admin-dashboard-page .dashboard-stat__label {
  color: #cff5ee;
  font-size: .75rem;
}

body.admin-dashboard-page .action-group + .action-group {
  margin-top: 1.75rem;
}

/* Group heading: a coloured bar then the title in Capital Case, as on the desktop dashboard. */
body.admin-dashboard-page .action-group__title {
  display: flex;
  align-items: center;
  gap: .6rem;
  font-size: 1.15rem;
  font-weight: 600;
  color: #0f172a;
  margin-bottom: .75rem;
}

body.admin-dashboard-page .action-group__title::before {
  content: "";
  width: .25rem;
  height: 1.4rem;
  border-radius: .125rem;
  background: var(--action-accent);
}

/* One accent per group; the same colours as the desktop app. */
body.admin-dashboard-page .action-mint {
  --action-accent: #2ed18a;
}

body.admin-dashboard-page .action-sky {
  --action-accent: #4cb8f0;
}

body.admin-dashboard-page .action-violet {
  --action-accent: #a78bfa;
}

body.admin-dashboard-page .action-rose {
  --action-accent: #f472a0;
}

/* Phones: one grouped list, each row a full-width tap target. Wider: a grid of compact tiles. */
body.admin-dashboard-page .action-grid {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(15.5rem, 1fr));
  gap: .75rem;
}

/* A coloured edge on the left (the group's accent) and a tinted tile behind the icon. */
body.admin-dashboard-page .action-card {
  position: relative;
  display: flex;
  align-items: center;
  gap: .85rem;
  height: 100%;
  padding: .9rem 1rem .9rem 1.25rem;
  overflow: hidden;
  background: #fff;
  border: 1px solid rgba(15, 23, 42, 0.08);
  border-radius: .5rem;
  box-shadow: var(--shadow-sm);
  color: inherit;
  text-decoration: none;
  transition: border-color .15s ease, box-shadow .15s ease;
}

body.admin-dashboard-page .action-card::before {
  content: "";
  position: absolute;
  inset: 0 auto 0 0;
  width: .25rem;
  background: var(--action-accent);
}

body.admin-dashboard-page .action-card:hover,
body.admin-dashboard-page .action-card:focus-visible {
  border-color: var(--action-accent);
  box-shadow: var(--shadow-md);
}

body.admin-dashboard-page .action-card__icon {
  width: 3rem;
  height: 3rem;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  align-self: flex-start;
  border-radius: .75rem;
  background: color-mix(in srgb, var(--action-accent) 18%, transparent);
  font-size: 1.4rem;
}

body.admin-dashboard-page .action-card__text {
  display: flex;
  flex-direction: column;
  min-width: 0;
  flex: 1 1 auto;
}

body.admin-dashboard-page .action-card__title {
  font-weight: 700;
  color: #0f172a;
  line-height: 1.25;
}

body.admin-dashboard-page .action-card__description {
  color: #64748b;
  font-size: .85rem;
  line-height: 1.35;
}

/* Item count pill, in the group's accent colour. */
body.admin-dashboard-page .action-card__count {
  align-self: center;
  flex-shrink: 0;
  min-width: 1.75rem;
  padding: .1rem .55rem;
  border-radius: 1rem;
  background: var(--action-accent);
  color: #0b1f1d;
  font-size: .75rem;
  font-weight: 700;
  line-height: 1.5;
  text-align: center;
  white-space: nowrap;
}

body.admin-dashboard-page .action-card__badges {
  display: flex;
  flex-wrap: wrap;
  gap: .4rem;
  margin-top: .4rem;
}

/* Status badges: the text carries the meaning, the colour only backs it up. */
body.admin-dashboard-page .action-badge {
  padding: .05rem .5rem;
  border-radius: 1rem;
  font-size: .7rem;
  font-weight: 600;
}

body.admin-dashboard-page .action-badge--good {
  background: rgba(46, 209, 138, .2);
  color: #0f7a4a;
}

body.admin-dashboard-page .action-badge--warn {
  background: rgba(245, 179, 61, .22);
  color: #8a5a00;
}

body.admin-dashboard-page .action-badge--info {
  background: rgba(100, 116, 139, .15);
  color: #475569;
}

[data-bs-theme="dark"] body.admin-dashboard-page .action-badge--good {
  color: #2ed18a;
}

[data-bs-theme="dark"] body.admin-dashboard-page .action-badge--warn {
  color: #f5b33d;
}

[data-bs-theme="dark"] body.admin-dashboard-page .action-badge--info {
  color: #aeb8c2;
}

body.admin-dashboard-page .action-card__chevron {
  color: #94a3b8;
  font-size: 1.4rem;
  line-height: 1;
  flex-shrink: 0;
}

@media (max-width: 575.98px) {
  body.admin-dashboard-page .action-grid {
    grid-template-columns: 1fr;
    gap: 0;
    background: #fff;
    border: 1px solid rgba(15, 23, 42, 0.08);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-sm);
    overflow: hidden;
  }

  body.admin-dashboard-page .action-grid li + li .action-card {
    border-top: 1px solid rgba(15, 23, 42, 0.06);
  }

  body.admin-dashboard-page .action-card {
    border: 0;
    border-radius: 0;
    box-shadow: none;
    padding: .8rem 1rem;
  }

  body.admin-dashboard-page .action-card:hover,
  body.admin-dashboard-page .action-card:active {
    background: #f8fafc;
    box-shadow: none;
  }

  body.admin-dashboard-page .action-card__icon {
    width: 2.5rem;
    height: 2.5rem;
    align-self: center;
    font-size: 1.2rem;
  }

  body.admin-dashboard-page .dashboard-hero {
    padding: 1.1rem 1.25rem;
  }
}

/* Bootstrap keeps its mid-tone outline-button colours in dark mode, which come out dim on the dark
   cards (Edit/Delete/Back to dashboard/reorder arrows). Use its lighter dark-mode emphasis tones for
   the resting text and border; hover/active still fill with the normal solid colour. */
[data-bs-theme="dark"] body.admin-dashboard-page .btn-outline-success {
  --bs-btn-color: #75b798;
  --bs-btn-border-color: #4d9a73;
}

[data-bs-theme="dark"] body.admin-dashboard-page .btn-outline-danger {
  --bs-btn-color: #ea868f;
  --bs-btn-border-color: #c95d68;
}

[data-bs-theme="dark"] body.admin-dashboard-page .btn-outline-secondary {
  --bs-btn-color: #c4c8cc;
  --bs-btn-border-color: #6c757d;
  --bs-btn-disabled-color: #8b9298;
}

/* The dashboard's text colours above are tuned for the light background; lift them in dark mode. */
[data-bs-theme="dark"] body.admin-dashboard-page .action-group__title,
[data-bs-theme="dark"] body.admin-dashboard-page .action-card__title {
  color: #f9fafb;
}

[data-bs-theme="dark"] body.admin-dashboard-page .action-card__description,
[data-bs-theme="dark"] body.admin-dashboard-page .action-card__chevron {
  color: #9ca3af;
}

[data-bs-theme="dark"] body.admin-dashboard-page .admin-breadcrumb a:hover,
[data-bs-theme="dark"] body.admin-dashboard-page .admin-breadcrumb a:focus-visible {
  color: #86efac;
}

@media (max-width: 575.98px) {
  [data-bs-theme="dark"] body.admin-dashboard-page .action-grid {
    background: #1f2937;
    border-color: #374151;
  }

  [data-bs-theme="dark"] body.admin-dashboard-page .action-grid li + li .action-card {
    border-top-color: #374151;
  }
}

@media (prefers-reduced-motion: reduce) {
  body.admin-dashboard-page .action-card {
    transition: none;
  }
}

/* The top bar stays one row at every width: the clock is dropped below lg and a long title truncates. */
@media (max-width: 991.98px) {
  body.admin-dashboard-page .admin-topbar__timestamp {
    display: none;
  }
}

@media (max-width: 575.98px) {
  body.admin-dashboard-page .admin-brand {
    min-width: 0;
  }

  body.admin-dashboard-page .admin-brand__title {
    overflow: hidden;
    text-overflow: ellipsis;
  }
}

.card-img-cover {
  width: 100%;
  aspect-ratio: 4 / 3;
  object-fit: cover;
  border-radius: var(--radius-sm);
}

/* Square, to match the 1/1 .product-image-frame on the details page, so a product's photo is cropped
   the same way on its card as on its own page. */
.product-card-img {
  aspect-ratio: 1 / 1;
  border-radius: 0;
}

.post-img-cover {
  width: 100%;
  aspect-ratio: 16 / 10;
  object-fit: cover;
  border-radius: var(--radius-sm);
}

/* About page gallery carousel: scales with viewport width instead of a fixed 600px tall on every
   screen size (which looked oversized on short mobile viewports) - 600px stays only as an upper
   bound on very wide screens. */
.about-gallery-img {
  width: 100%;
  aspect-ratio: 16 / 9;
  object-fit: cover;
  max-height: 600px;
}

/* About page post photos and product details photos: each image is a bare button that opens the
   #postLightbox carousel (_PhotoLightbox.cshtml). */
.post-gallery-trigger {
  position: relative;
  display: block;
  width: 100%;
  padding: 0;
  border: 0;
  background: none;
  border-radius: var(--radius-sm);
  cursor: zoom-in;
}

.post-gallery-trigger:focus-visible {
  outline: 3px solid var(--brand-teal);
  outline-offset: 2px;
}

.post-photo-count {
  position: absolute;
  right: .5rem;
  bottom: .5rem;
  padding: .2rem .55rem;
  border-radius: 999px;
  background: rgba(0, 0, 0, .6);
  color: #fff;
  font-size: .8rem;
  line-height: 1.4;
  pointer-events: none;
}

/* Always four columns, so a post with two extra photos keeps the same thumb size as one with four. */
.post-thumb-strip {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: .5rem;
}

.post-thumb {
  display: block;
  width: 100%;
  aspect-ratio: 1 / 1;
  object-fit: cover;
  border-radius: .375rem;
}

.post-thumb-more {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: .375rem;
  background: rgba(0, 0, 0, .55);
  color: #fff;
  font-weight: 600;
  font-size: 1.1rem;
  pointer-events: none;
}

.post-lightbox .modal-body {
  min-height: 0;
}

.post-lightbox-img {
  max-width: 100%;
  max-height: calc(100vh - 5rem);
  object-fit: contain;
}

/* Fallback shown in place of a product/category/post/banner image when nothing has been uploaded:
   the brand logo itself. It carries the same width/aspect-ratio/border-radius class as the real <img>
   it replaces, so swapping between the two never shifts surrounding layout.

   Must stay after those sizing classes in this file: object-fit overrides the `cover` they set (same
   specificity, so source order decides) and the logo is drawn whole rather than cropped to fill.
   height:100% resolves against a definite parent (the 1/1 .product-image-frame) and falls back to auto
   against an auto-height one, which is what lets the sizing class's aspect-ratio apply on cards. */
.img-placeholder-logo {
  width: 100%;
  height: 100%;
  object-fit: contain;
  padding: 6%;
}

/* The logo on a theme-coloured background (_BrandLogo.cshtml) comes in two files: black text for light mode,
   white text for dark. `revert` hands display back to the browser default (inline) for the one being shown. */
.brand-logo-dark {
  display: none;
}

[data-bs-theme="dark"] .brand-logo-light {
  display: none;
}

[data-bs-theme="dark"] .brand-logo-dark {
  display: revert;
}

.home-banner-img {
  width: 100%;
  aspect-ratio: 4 / 3;
  object-fit: cover;
  border-radius: var(--radius-sm);
}

.price-original {
  color: var(--bs-secondary-color);
  text-decoration: line-through;
  margin-right: .5rem;
}

.price-sale {
  color: #dc2626;
  font-weight: 600;
}

[data-bs-theme="dark"] .price-sale {
  color: #ff8080;
}

/* "From" in front of the cheapest size's price, for a product sold in several sizes. */
.price-from {
  color: var(--bs-secondary-color);
  font-size: .85em;
  margin-right: .25rem;
}

/* Product details size picker: one pill per size (name, this product's details for it, its price), the
   picked one in the brand teal. A sold-out size's radio is disabled, so its pill greys out and can't be picked. */
.size-option {
  display: inline-flex;
  flex-direction: column;
  align-items: flex-start;
  min-width: 7rem;
  padding: .5rem .85rem;
  border: 1px solid var(--bs-border-color);
  border-radius: .75rem;
  cursor: pointer;
  line-height: 1.25;
  transition: border-color .15s ease, box-shadow .15s ease;
}

.size-option:hover {
  border-color: var(--brand-teal);
}

.size-option-name {
  font-weight: 600;
}

.size-option-details,
.size-option-price {
  font-size: .85rem;
  color: var(--bs-secondary-color);
}

.btn-check:checked + .size-option {
  border-color: var(--brand-teal);
  box-shadow: 0 0 0 .15rem var(--brand-teal);
}

.btn-check:focus-visible + .size-option {
  outline: 2px solid var(--brand-teal);
  outline-offset: 2px;
}

.btn-check:disabled + .size-option {
  cursor: not-allowed;
  opacity: .5;
  text-decoration: line-through;
}

.colour-swatch-dot {
  display: inline-block;
  width: 1rem;
  height: 1rem;
  border-radius: 50%;
  border: 1px solid rgba(0, 0, 0, .15);
  flex: 0 0 auto;
}

.colour-swatch-tag,
.sun-exposure-tag {
  display: inline-flex;
  align-items: center;
  gap: .4rem;
  padding: .3rem .7rem;
  border: 1px solid var(--bs-border-color);
  border-radius: 999px;
  font-size: .85rem;
  background: var(--bs-tertiary-bg);
}

.sun-exposure-tag .bi {
  color: var(--brand-teal);
}

/* Products page filters: on desktop they're a left sidebar that stays in view under the sticky
   header while the grid scrolls, and scrolls itself if it's taller than the window. */
@media (min-width: 992px) {
  .product-filter-sidebar {
    position: sticky;
    top: calc(var(--site-header-height) + 1rem);
    max-height: calc(100vh - var(--site-header-height) - 2rem);
    overflow-y: auto;
  }
}

.colour-swatch-picker {
  display: flex;
  flex-wrap: wrap;
  gap: .5rem;
}

.colour-swatch-option {
  display: inline-flex;
  align-items: center;
  gap: .4rem;
  padding: .35rem .75rem;
  border: 1px solid var(--bs-border-color);
  border-radius: 999px;
  font-size: .85rem;
  background: var(--bs-body-bg);
  cursor: pointer;
  user-select: none;
  transition: border-color .15s ease, box-shadow .15s ease, background-color .15s ease;
}

.colour-swatch-option:hover {
  border-color: var(--bs-secondary-color);
}

.btn-check:checked + .colour-swatch-option,
.btn-check:focus-visible + .colour-swatch-option {
  border-color: var(--bs-success);
  background-color: rgba(25, 135, 84, .08);
  box-shadow: 0 0 0 1px var(--bs-success);
}

.btn-check:focus-visible + .colour-swatch-option {
  outline: 2px solid var(--bs-success);
  outline-offset: 1px;
}

.img-hover {
  box-shadow: 0 4px 10px rgba(15, 23, 42, .08);
  transition: transform .2s ease, box-shadow .2s ease, opacity .2s ease;
}

.img-hover:hover {
  transform: scale(1.035);
  box-shadow: 0 10px 24px rgba(15, 23, 42, .16);
  opacity: .95;
}

@media (prefers-reduced-motion: reduce) {
  .img-hover,
  .img-hover:hover {
    transition: none;
    transform: none;
  }
}

.product-image-frame {
  position: relative;
  width: 100%;
  aspect-ratio: 1 / 1;
  overflow: hidden;
  background: var(--bs-tertiary-bg);
}

.product-main-img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  cursor: zoom-in;
}

/* Out of stock: the product stays browsable, but its image is greyed out under a banner so it reads
   as unavailable at a glance. Used on the catalogue/home cards, the home banner and the details page. */
.product-media {
  position: relative;
  display: block;
}

.product-media.is-out-of-stock img,
.product-media.is-out-of-stock img:hover {
  filter: grayscale(1);
  opacity: .55;
}

.out-of-stock-banner {
  position: absolute;
  top: 50%;
  left: 0;
  right: 0;
  z-index: 1;
  transform: translateY(-50%);
  padding: .5rem .75rem;
  background: rgba(15, 23, 42, .8);
  color: #fff;
  font-weight: 700;
  letter-spacing: .08em;
  text-transform: uppercase;
  text-align: center;
  pointer-events: none;
}

.stock-status {
  display: inline-flex;
  align-items: center;
  gap: .4rem;
  padding: .3rem .75rem;
  border-radius: 999px;
  font-size: .875rem;
  font-weight: 600;
}

.stock-status--in {
  background-color: var(--brand-mint-soft);
  color: var(--brand-teal-active);
}

.stock-status--out {
  background-color: var(--bs-secondary-bg);
  color: var(--bs-emphasis-color);
}

/* The details page's lead image is a .post-gallery-trigger like an About post's, but it has to fill the
   square frame rather than size itself to the image. */
.product-image-frame > .post-gallery-trigger {
  height: 100%;
  border-radius: 0;
}

.product-description {
  color: var(--bs-secondary-color);
  line-height: 1.7;
}

.home-section + .home-section {
  margin-top: 5rem;
}

@media (min-width: 992px) {
  .home-section + .home-section {
    margin-top: 6.5rem;
  }
}

/* "Shop by category" on the home page: one pill per category, linking to the filtered catalogue.
   Wraps from md up; below that it's one sideways-scrolling row so it doesn't stack down the page.
   "All plants" (the first chip) wears the brand mint->teal gradient; every other chip takes the next
   --garden-* accent in turn (--chip-accent). Text always stays var(--bs-body-color) on a tint of the
   accent, never on the solid accent, so contrast holds in both themes whatever the hue. */
.category-chips {
  display: flex;
  flex-wrap: nowrap;
  gap: .75rem;
  overflow-x: auto;
  scroll-snap-type: x proximity;
  scrollbar-width: none;
  -ms-overflow-style: none;
  padding: .35rem .125rem .5rem;
}

.category-chips::-webkit-scrollbar {
  display: none;
}

.category-chips > li {
  flex: 0 0 auto;
  scroll-snap-align: start;
  --chip-accent: var(--garden-leaf);
}

.category-chips > li:nth-child(6n + 3) { --chip-accent: var(--garden-teal); }
.category-chips > li:nth-child(6n + 4) { --chip-accent: var(--garden-sun); }
.category-chips > li:nth-child(6n + 5) { --chip-accent: var(--garden-blossom); }
.category-chips > li:nth-child(6n + 6) { --chip-accent: var(--garden-lavender); }
.category-chips > li:nth-child(6n + 7) { --chip-accent: var(--garden-terracotta); }

@media (min-width: 768px) {
  .category-chips {
    flex-wrap: wrap;
    overflow-x: visible;
  }
}

/* position: relative makes each chip the containing block for its absolutely-positioned
   .visually-hidden "plants" text. Without it that text escaped the chip row's overflow-x scroller
   and widened the whole page on phones (a blank strip you could scroll sideways into). */
.category-chip {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: .5rem;
  padding: .55rem .6rem .55rem .9rem;
  border: 1.5px solid color-mix(in srgb, var(--chip-accent) 65%, var(--bs-body-bg));
  border-radius: 999px;
  background-color: color-mix(in srgb, var(--chip-accent) 14%, var(--bs-body-bg));
  color: var(--bs-body-color);
  font-weight: 600;
  text-decoration: none;
  white-space: nowrap;
  transition: background-color .15s ease, border-color .15s ease, transform .15s ease, box-shadow .15s ease;
}

/* A solid dot of the accent: the one place the full-strength colour shows. Decorative only. */
.category-chip::before {
  content: "";
  flex: 0 0 auto;
  width: .6rem;
  height: .6rem;
  border-radius: 50%;
  background-color: var(--chip-accent);
}

.category-chip:hover {
  background-color: color-mix(in srgb, var(--chip-accent) 28%, var(--bs-body-bg));
  border-color: var(--chip-accent);
  color: var(--bs-body-color);
  box-shadow: 0 4px 12px color-mix(in srgb, var(--chip-accent) 35%, transparent);
}

.category-chip:focus-visible {
  outline: 3px solid var(--brand-teal);
  outline-offset: 2px;
}

.category-chip-count {
  display: inline-block;
  min-width: 1.75rem;
  padding: .1rem .45rem;
  border-radius: 999px;
  background-color: color-mix(in srgb, var(--chip-accent) 34%, var(--bs-body-bg));
  color: var(--bs-body-color);
  font-size: .8rem;
  font-weight: 700;
  text-align: center;
}

/* "All plants": the brand gradient as a fill, with the dark ink the home banner's button uses. The
   gradient stops short of full teal so the ink keeps AA contrast across its whole width. */
.category-chips > li:first-child .category-chip {
  border-color: transparent;
  background: linear-gradient(135deg, var(--brand-mint) 0%, color-mix(in srgb, var(--brand-teal) 55%, var(--brand-mint)) 100%);
  color: var(--brand-ink);
}

.category-chips > li:first-child .category-chip::before {
  background-color: var(--brand-ink);
}

.category-chips > li:first-child .category-chip:hover {
  box-shadow: 0 4px 12px color-mix(in srgb, var(--brand-teal) 40%, transparent);
}

.category-chips > li:first-child .category-chip-count {
  background-color: rgba(255, 255, 255, .7);
  color: var(--brand-ink);
}

@media (prefers-reduced-motion: no-preference) {
  .category-chip:hover {
    transform: translateY(-2px);
  }
}

[data-bs-theme="dark"] .btn-outline-dark {
  --bs-btn-color: var(--bs-body-color);
  --bs-btn-border-color: var(--bs-border-color);
  --bs-btn-hover-bg: var(--bs-body-color);
  --bs-btn-hover-color: var(--bs-body-bg);
  --bs-btn-hover-border-color: var(--bs-body-color);
  --bs-btn-active-bg: var(--bs-body-color);
  --bs-btn-active-color: var(--bs-body-bg);
  --bs-btn-active-border-color: var(--bs-body-color);
}
/* ---- Admin: Print Labels (/admin/labels) ---------------------------------------------------------------
   Each .label-sheet is one A4 page split into a grid of .price-label cells. Label text is sized in container
   units (cqh/cqw) against the label itself, so one design scales from the 2-up sign to the 21-up sticker. */

body.admin-dashboard-page .labels-col-check {
  width: 2.5rem;
}

body.admin-dashboard-page .labels-col-copies {
  width: 6.5rem;
}

body.admin-dashboard-page .labels-layout-option + .labels-layout-option {
  margin-top: 0.5rem;
}

.label-print-area {
  --label-lime: #9ccc1c;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1.5rem;
  padding: 0 1rem 3rem;
  overflow-x: auto;
}

.label-sheet {
  width: 210mm;
  height: 297mm;
  flex: 0 0 auto;
  display: grid;
  grid-template-columns: repeat(var(--label-cols, 1), 1fr);
  grid-template-rows: repeat(var(--label-rows, 2), 1fr);
  background: #fff;
  box-shadow: 0 0.5rem 1.5rem rgba(15, 23, 42, 0.15);
  box-sizing: border-box;
  overflow: hidden;
}

.label-sheet--landscape {
  width: 297mm;
  height: 210mm;
}

/* 1-, 2- and 4-per-page sheets leave a white margin and gaps (--label-gutter) for laminating; the label edge is then a
   solid frame rather than a cut line, because the cut goes down the middle of the gap. */
.label-sheet--spaced {
  padding: var(--label-gutter);
  gap: var(--label-gutter);
}

.label-sheet--spaced .price-label {
  outline-style: solid;
}

.price-label {
  container-type: size;
  min-width: 0;
  min-height: 0;
  /* Light dashed cut guides; they print too, so the sheet can be trimmed with a guillotine or scissors. */
  outline: 0.2mm dashed #b8c0cc;
  outline-offset: -0.1mm;
  overflow: hidden;
  -webkit-print-color-adjust: exact;
  print-color-adjust: exact;
}

.price-label--blank {
  outline-color: #e5e7eb;
}

.price-label__inner {
  /* Width left for the text column; the price is sized from it (see .price-label__price). */
  --label-main-width: 88cqw;
  --label-qr-size: 32cqh;
  height: 100%;
  box-sizing: border-box;
  padding: 5cqh 6cqw;
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  column-gap: 4cqw;
  color: #1a1a1a;
  font-family: "Segoe UI", Calibri, Arial, sans-serif;
}

.price-label--qr .price-label__inner {
  --label-main-width: calc(84cqw - var(--label-qr-size));
  grid-template-columns: minmax(0, 1fr) var(--label-qr-size);
}

.price-label__main {
  min-width: 0;
  min-height: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: space-between;
  text-align: center;
}

.price-label__qr {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 1.5cqh;
}

.price-label__qr svg {
  display: block;
  width: 100%;
  height: auto;
  fill: #000;
}

.price-label__qr-caption {
  font-size: min(4.5cqh, 3.2cqw);
  color: #333;
  white-space: nowrap;
}

.label-qr-defs {
  position: absolute;
  width: 0;
  height: 0;
  overflow: hidden;
}

.price-label__logo {
  height: 24cqh;
  max-width: 70cqw;
  object-fit: contain;
}

.price-label__price-block {
  line-height: 1;
}

.price-label__price {
  /* Also capped so --price-chars characters (set per label) fit the text column, e.g. "R 1,250" beside a QR code. */
  font-size: min(30cqh, 20cqw, calc(var(--label-main-width) / (var(--price-chars, 5) * 0.6)));
  font-weight: 600;
  letter-spacing: -0.02em;
  white-space: nowrap;
}

.price-label__was {
  font-size: min(7cqh, 5cqw);
  margin-bottom: 1.5cqh;
  color: #444;
}

.price-label__sale {
  display: inline-block;
  padding: 0.3cqh 2cqw;
  margin-right: 1cqw;
  border-radius: 999px;
  background: var(--label-lime);
  color: #111;
  font-weight: 700;
  text-transform: uppercase;
}

.price-label__name {
  font-size: min(9cqh, 6.5cqw);
  line-height: 1.25;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

/* A sized product's size, on its own line under the name; it shares the name's two-line clamp. */
.price-label__size {
  display: block;
  font-size: 0.8em;
  font-weight: 600;
}

.price-label__contact {
  font-size: min(7cqh, 5cqw);
  letter-spacing: 0.03em;
  padding-top: 1.5cqh;
  border-top: max(0.6cqh, 0.4mm) solid var(--label-lime);
  white-space: nowrap;
}

.price-label__contact > * {
  line-height: 1.2;
}

.price-label__website {
  font-size: 0.8em;
  letter-spacing: 0.01em;
  color: #333;
}

/* A sale label carries an extra "Was" line, so give back that height from the logo and the price. */
.price-label--sale .price-label__logo {
  height: 19cqh;
}

.price-label--sale .price-label__price {
  font-size: min(26cqh, 20cqw, calc(var(--label-main-width) / (var(--price-chars, 5) * 0.6)));
}

@media print {
  /* The public site's own chrome - printing a product page or the policy page previously baked
     in the full gradient header, nav, footer, and cookie banner, none of which is useful on paper. */
  .site-header,
  .footer,
  .cookie-banner {
    display: none !important;
  }

  body.admin-dashboard-page {
    background: #fff;
    min-height: 0;
  }

  body.admin-dashboard-page .admin-topbar,
  body.admin-dashboard-page .admin-subnav,
  body.admin-dashboard-page .labels-controls {
    display: none !important;
  }

  body.admin-dashboard-page .admin-dashboard-main {
    padding: 0 !important;
    margin: 0 !important;
  }

  .label-print-area {
    display: block;
    padding: 0;
    overflow: visible;
  }

  .label-sheet {
    box-shadow: none;
    /* A hair under 297mm: an exact-height sheet can round over and push a blank page between sheets. */
    height: 296.5mm;
    break-after: page;
    page-break-after: always;
  }

  .label-sheet--landscape {
    height: 209.5mm;
  }

  .label-sheet:last-child {
    break-after: auto;
    page-break-after: auto;
  }
}

/* Step timeline in the admin product form (_ProductSteps.cshtml), matching the desktop app's StepTimeline. */
.admin-stepper {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  margin: 0 0 1rem;
  padding: 0;
  list-style: none;
}

.admin-step {
  position: relative;
}

/* The line joining this step's circle to the one before it. */
.admin-step:not(:first-child)::before {
  content: "";
  position: absolute;
  top: calc(0.5rem + 15px);
  left: calc(-50% + 1.5rem);
  right: calc(50% + 1.5rem);
  height: 2px;
  background: var(--bs-border-color);
}

.admin-step.is-done + .admin-step::before {
  background: var(--bs-success);
}

.admin-step-button {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  width: 100%;
  height: 100%;
  padding: 0.5rem 0.25rem 0.75rem;
  border: 0;
  border-radius: 0.5rem;
  background: transparent;
  color: var(--bs-body-color);
  text-align: center;
}

.admin-step-button:hover,
.admin-step.is-selected .admin-step-button {
  background: var(--bs-tertiary-bg);
}

.admin-step-button:focus-visible {
  outline: 2px solid var(--bs-success);
  outline-offset: 1px;
}

/* The bar under the step being shown, separate from whether that step is finished. */
.admin-step.is-selected .admin-step-button::after {
  content: "";
  position: absolute;
  bottom: 0;
  left: 50%;
  width: 48px;
  height: 3px;
  border-radius: 2px;
  background: var(--bs-success);
  transform: translateX(-50%);
}

.admin-step-circle {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  margin-bottom: 0.25rem;
  border: 2px solid var(--bs-border-color);
  border-radius: 50%;
  color: var(--bs-secondary-color);
  font-size: 0.875rem;
}

.admin-step-tick {
  display: none;
}

.admin-step.is-current .admin-step-circle {
  border-color: var(--bs-success);
  color: var(--bs-body-color);
  font-weight: 700;
}

.admin-step.is-done .admin-step-circle {
  border-color: var(--bs-success);
  background: var(--bs-success);
  color: #fff;
}

.admin-step.is-done .admin-step-number {
  display: none;
}

.admin-step.is-done .admin-step-tick {
  display: inline;
}

.admin-step-title {
  font-size: 0.875rem;
  font-weight: 600;
}

.admin-step-detail {
  color: var(--bs-secondary-color);
  font-size: 0.75rem;
}

@media (max-width: 575.98px) {
  .admin-step-detail {
    display: none;
  }
}
