/* ============================================================================
   assets/css/cato.css — the CATO layer.

   Loaded AFTER base.css and theme.css, on both the public site and the admin.

   Why a fourth stylesheet instead of growing theme.css: the chassis split is
   base.css (never redesigned) then theme.css (tokens, restyled per client).
   This file is the third thing — components that only exist on this build: the
   catalog grid, the blog, the service tabs, the diamond-plate motif. Keeping
   them separate means a future rebrand touches theme.css tokens and leaves the
   components alone, and a component fix does not risk the tokens.

   Brand rule inherited from the approved rebuild: BLUE (#0000FE) AND BLACK
   ONLY. No orange anywhere.
   ============================================================================ */

/* --- Type ------------------------------------------------------------------
   Oswald is condensed and uppercase-leaning, so headings need a little tracking
   back rather than the chassis default of -.02em, which over-tightens it. Body
   copy stays Roboto — Oswald set at paragraph length is genuinely hard to read. */
h1, h2, h3, h4,
.brand__name,
.shop-card__title,
.blog-card__title {
  font-family: var(--font-display);
  font-weight: 600;
  letter-spacing: .01em;
}
h1 { font-weight: 700; }

/* --- Diamond plate ---------------------------------------------------------
   The recurring texture in the CATO identity. Drawn in CSS rather than shipped
   as an image: it is a repeating geometric pattern, so gradients cost no
   request and stay sharp at any density.

   Deliberately very low contrast, and applied by class rather than globally. On
   a page full of product photography this reads as noise if it is everywhere. */
.diamond-plate {
  background-color: var(--color-bg-sunk);
  background-image:
    repeating-linear-gradient( 45deg, rgba(8,8,8,.05) 0 2px, transparent 2px 9px),
    repeating-linear-gradient(-45deg, rgba(8,8,8,.05) 0 2px, transparent 2px 9px);
  background-size: 18px 18px;
}
.diamond-plate--dark {
  background-color: #111111;
  color: #ffffff;
  background-image:
    repeating-linear-gradient( 45deg, rgba(255,255,255,.06) 0 2px, transparent 2px 9px),
    repeating-linear-gradient(-45deg, rgba(255,255,255,.06) 0 2px, transparent 2px 9px);
}

/* --- Dark sections ---------------------------------------------------------
   #0000FE on near-black is about 1.6:1 and effectively invisible. The approved
   rebuild solves this by flipping the brand colour to WHITE inside dark bands,
   and so does this — scoped to the section so it cannot leak outward. */
.section--dark {
  background: #111111;
  color: #ffffff;
  --color-text: #ffffff;
  --color-text-muted: #C9C9C9;
  --color-accent-text: #ffffff;
  --color-primary: #ffffff;
  --color-border: rgba(255,255,255,.18);
}
.section--dark a { color: #ffffff; text-decoration-thickness: 2px; }

/* ===========================================================================
   CATALOG LISTING
   =========================================================================== */
.shop-layout { display: grid; grid-template-columns: 16rem 1fr; gap: 2rem; align-items: start; }
@media (max-width: 60rem) { .shop-layout { grid-template-columns: 1fr; } }

.shop-side__label { font-family: var(--font-display); font-size: .95rem; text-transform: uppercase; letter-spacing: .06em; margin: 0 0 .5rem; }
.shop-side__list { list-style: none; margin: 0 0 1.5rem; padding: 0; }
.shop-side__list a { display: flex; justify-content: space-between; gap: .5rem; padding: .35rem .5rem; border-radius: var(--radius-sm); text-decoration: none; color: var(--color-text); }
.shop-side__list a:hover { background: var(--color-bg-sunk); }
.shop-side__list a.is-active { background: var(--color-primary); color: #ffffff; }
/* No opacity on the count: at .75 it was 3.34:1 on the hover tint (gate, 2026-10-26).
   Muted ink is AA on its own; the active row's white comes through inherit. */
.shop-side__n { color: var(--color-text-muted); font-variant-numeric: tabular-nums; }
.shop-side__list a.is-active .shop-side__n { color: inherit; }

.shop-toolbar { display: flex; flex-wrap: wrap; gap: .75rem; align-items: end; margin-bottom: 1rem; }
.shop-toolbar__search { flex: 1 1 16rem; }
.shop-count { color: var(--color-text-muted); margin: 0 0 1rem; }

.shop-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr)); gap: 1.25rem; }
.shop-card { display: flex; flex-direction: column; background: var(--color-bg-alt); border: 1px solid var(--color-border); border-radius: 12px; overflow: hidden; }
.shop-card.is-out { opacity: .72; }
.shop-card__media { display: block; position: relative; aspect-ratio: 1 / 1; background: var(--color-bg-sunk); }

/* object-fit: contain, NOT cover. This catalog is manufacturer product shots on
   white, not lifestyle photography — cropping a service body to fill a square
   cuts the ends off the thing being sold. */
.shop-card__media img { width: 100%; height: 100%; object-fit: contain; padding: .75rem; }

.shop-card__flag { position: absolute; top: .5rem; left: .5rem; background: var(--color-primary); color: #ffffff; font-size: .75rem; padding: .15rem .5rem; border-radius: 999px; }
.shop-card__flag--out { background: #5C5C5C; }
.shop-card__body { padding: .85rem 1rem 1rem; display: flex; flex-direction: column; gap: .35rem; flex: 1; }
.shop-card__brand { font-size: .75rem; text-transform: uppercase; letter-spacing: .06em; color: var(--color-text-muted); }
.shop-card__title { font-size: 1rem; margin: 0; }
.shop-card__link { text-decoration: none; color: var(--color-text); }
.shop-card__link:hover { color: var(--color-primary); }
.shop-card__blurb { font-size: .875rem; color: var(--color-text-muted); margin: 0; }
.shop-card__foot { margin-top: auto; padding-top: .5rem; display: flex; align-items: center; justify-content: space-between; gap: .5rem; flex-wrap: wrap; }

/* "Call for Pricing" is the majority state on this catalog (29 of 48), so it is
   styled as a deliberate invitation in the brand colour rather than as a
   missing value in grey. */
.shop-price { margin: 0; font-family: var(--font-display); font-size: 1.05rem; }
.shop-price__ask { font-weight: 600; color: var(--color-primary); }
.shop-price__was { color: var(--color-text-muted); font-weight: 400; margin-left: .35rem; }

.shop-badge { font-size: .75rem; padding: .15rem .5rem; border-radius: 999px; border: 1px solid var(--color-border-strong); }
.shop-badge--low { background: var(--color-bg-sunk); }
.shop-badge--out { background: #5C5C5C; color: #ffffff; border-color: #5C5C5C; }

.shop-pager, .admin-pager { display: flex; gap: .35rem; flex-wrap: wrap; margin-top: 1.5rem; }
.shop-pager a, .admin-pager a { padding: .35rem .7rem; border: 1px solid var(--color-border-strong); border-radius: var(--radius-sm); text-decoration: none; color: var(--color-text); }
.shop-pager a.is-active, .admin-pager a.is-active { background: var(--color-primary); color: #ffffff; border-color: var(--color-primary); }

.shop-empty { padding: 2rem; text-align: center; background: var(--color-bg-sunk); border-radius: 12px; }

/* ===========================================================================
   PRODUCT DETAIL
   =========================================================================== */
.shop-pdp { display: grid; grid-template-columns: minmax(0,1fr) minmax(0,1fr); gap: 2rem; align-items: start; }
@media (max-width: 55rem) { .shop-pdp { grid-template-columns: 1fr; } }
.shop-pdp__img { width: 100%; height: auto; background: var(--color-bg-alt); border: 1px solid var(--color-border); border-radius: 12px; }
.shop-pdp__thumbs { display: flex; gap: .5rem; list-style: none; padding: 0; margin: .75rem 0 0; flex-wrap: wrap; }
.shop-pdp__thumb { padding: 0; background: none; border: 2px solid var(--color-border); border-radius: var(--radius-sm); cursor: pointer; line-height: 0; }
.shop-pdp__thumb.is-active { border-color: var(--color-primary); }
.shop-pdp__brand { text-transform: uppercase; letter-spacing: .06em; font-size: .8rem; margin: 0 0 .25rem; }
.shop-pdp__title { margin: 0 0 .5rem; }
.shop-pdp__blurb { color: var(--color-text-muted); }
.shop-pdp__meta { display: flex; align-items: center; gap: .75rem; flex-wrap: wrap; margin: 1rem 0; }
.shop-pdp__avail { font-size: .9rem; color: var(--color-text-muted); }
.shop-pdp__avail.is-gone { color: #5C5C5C; font-weight: 500; }
.shop-pdp__sku { font-size: .85rem; color: var(--color-text-muted); }
.shop-pdp__highlights { padding-left: 1.1rem; }
.shop-pdp__cta { display: flex; gap: .6rem; flex-wrap: wrap; margin: 1.25rem 0 .5rem; }
.shop-pdp__note { font-size: .875rem; color: var(--color-text-muted); }
.shop-pdp__body, .shop-pdp__specs, .shop-pdp__quote, .shop-related { margin-top: 2.5rem; }

/* PDP lower half: copy left, quote form right.

   Everything below the gallery used to be one full-width stack, which left a
   half-empty page beside a 65ch description and pushed the only lead-capturing
   thing on the page below the fold. Two columns, and the form sticks while the
   copy scrolls past it.

   1.6fr / 1fr rather than 2fr / 1fr: the form has four inputs on one row inside
   it (.shop-quote__grid is auto-fit minmax(13rem)), so a narrower right column
   makes it collapse to a single stacked column and grow taller than the copy. */
.shop-pdp__detail {
  display: grid;
  gap: var(--sp-10, 2.5rem);
  align-items: start;
}
@media (min-width: 960px) {
  .shop-pdp__detail { grid-template-columns: 1.6fr 1fr; }
  .shop-pdp__detail--solo { grid-template-columns: minmax(0, 34rem); }
  .shop-pdp__detail > .shop-pdp__quote {
    position: sticky;
    /* clears the sticky header; matches the scroll-margin used elsewhere */
    top: calc(var(--cato-header-h, 88px) + 1.5rem);
  }
}
/* The children already carry margin-top: 2.5rem from the rule above, which
   inside a grid doubles the gap and knocks the two columns out of alignment. */
.shop-pdp__detail > *,
.shop-pdp__detail-main > :first-child { margin-top: 0; }
.shop-pdp__detail-main > * + * { margin-top: 2.5rem; }

/* The form is a card now that it sits beside the copy rather than under it. */
.shop-pdp__detail > .shop-pdp__quote {
  background: var(--color-bg-alt, #FFFFFF);
  border: 1px solid var(--color-border);
  border-radius: var(--cato-radius-lg, 14px);
  padding: var(--sp-6, 1.5rem);
  box-shadow: var(--cato-shadow-sm);
}
.shop-pdp__detail > .shop-pdp__quote > h2 { margin-top: 0; }

.shop-specs { width: 100%; border-collapse: collapse; }
.shop-specs th, .shop-specs td { text-align: left; padding: .55rem .75rem; border-bottom: 1px solid var(--color-border); vertical-align: top; }
.shop-specs th { width: 40%; font-weight: 500; color: var(--color-text-muted); }

.shop-quote__grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr)); gap: .75rem; }
.shop-flash { padding: .7rem .9rem; border-radius: var(--radius-sm); background: var(--color-bg-sunk); }
.shop-flash.is-error { background: #FDEAEE; color: #7A1024; }
.shop-flash.is-ok { background: #E7F5EC; color: #0B5C30; }
.shop-note { padding: .7rem .9rem; background: var(--color-bg-sunk); border-radius: var(--radius-sm); }

/* The toast is hidden by default and revealed by catalog.js. Uses visibility +
   opacity rather than display:none so the live region stays in the a11y tree
   and the message is actually announced. */
.shop-toast { position: fixed; left: 50%; bottom: 1.5rem; transform: translateX(-50%) translateY(1rem); background: #111111; color: #ffffff; padding: .75rem 1.1rem; border-radius: 999px; opacity: 0; visibility: hidden; transition: opacity .2s, transform .2s; z-index: 60; max-width: min(90vw, 34rem); }
.shop-toast.is-visible { opacity: 1; visibility: visible; transform: translateX(-50%) translateY(0); }

/* ===========================================================================
   BLOG
   =========================================================================== */
.blog-tags { display: flex; gap: .4rem; flex-wrap: wrap; margin-bottom: 1.5rem; }
.blog-tags a, .blog-tag { padding: .25rem .65rem; border: 1px solid var(--color-border-strong); border-radius: 999px; text-decoration: none; color: var(--color-text); font-size: .85rem; }
.blog-tags a.is-active { background: var(--color-primary); color: #ffffff; border-color: var(--color-primary); }
.blog-tags__n { opacity: .75; }

.blog-list { display: grid; gap: 1.5rem; }
.blog-card { display: grid; grid-template-columns: 14rem 1fr; gap: 1.25rem; align-items: start; }
@media (max-width: 45rem) { .blog-card { grid-template-columns: 1fr; } }
.blog-card__media img { width: 100%; height: auto; border-radius: 12px; }
.blog-card__meta { font-size: .85rem; color: var(--color-text-muted); margin: 0 0 .25rem; }
.blog-card__title { margin: 0 0 .4rem; font-size: 1.3rem; }
.blog-card__title a { text-decoration: none; color: var(--color-text); }
.blog-card__title a:hover { color: var(--color-primary); }
.blog-card__excerpt { margin: 0 0 .4rem; color: var(--color-text-muted); }

.post-head { margin-bottom: 1.5rem; }
.post-head__meta { color: var(--color-text-muted); font-size: .9rem; margin: 0 0 .35rem; }
.post-head__tags { display: flex; gap: .4rem; flex-wrap: wrap; margin-top: .75rem; }
.post-cover img { width: 100%; height: auto; border-radius: 12px; margin-bottom: 1.5rem; }
.post-body { max-width: var(--reading-max); }
.post-body h2 { margin-top: 2rem; }
.post-body img { max-width: 100%; height: auto; border-radius: var(--radius-sm); }
.post-body blockquote { margin: 1.5rem 0; padding-left: 1rem; border-left: 3px solid var(--color-primary); color: var(--color-text-muted); }
.post-foot { margin-top: 2.5rem; padding-top: 1rem; border-top: 1px solid var(--color-border); }
.post-more { margin-top: 2rem; }
.post-more__list { list-style: none; padding: 0; margin: 0; display: grid; gap: .6rem; }
.post-more__list li { display: flex; justify-content: space-between; gap: 1rem; border-bottom: 1px solid var(--color-border); padding-bottom: .6rem; }
.post-more__list time { color: var(--color-text-muted); font-size: .85rem; white-space: nowrap; }

/* ===========================================================================
   ADMIN COMPONENTS ADDED ON THIS BUILD

   The rest of the admin styling lives in shop.css, inherited from the ecommerce
   template. These are the classes the new screens introduced.
   =========================================================================== */
.admin-tabs { display: flex; gap: .35rem; flex-wrap: wrap; border-bottom: 1px solid var(--color-border); margin-bottom: 1.25rem; }
.admin-tab { padding: .5rem .9rem; text-decoration: none; color: var(--color-text); border-bottom: 3px solid transparent; margin-bottom: -1px; }
.admin-tab.is-active { border-bottom-color: var(--color-primary); color: var(--color-primary); font-weight: 500; }
.admin-tab__n { display: inline-block; min-width: 1.4em; text-align: center; background: var(--color-bg-sunk); border-radius: 999px; font-size: .78rem; padding: 0 .35rem; margin-left: .25rem; }

.admin-filters { display: flex; gap: .75rem; align-items: end; flex-wrap: wrap; margin-bottom: 1rem; }
.admin-muted { color: var(--color-text-muted); }
.admin-field__opt { font-weight: 400; color: var(--color-text-muted); }
.admin-table--kv th { width: 32%; text-align: left; font-weight: 500; color: var(--color-text-muted); }
.admin-flash--info { background: var(--color-bg-sunk); border-left: 3px solid var(--color-primary); }

.btn-sm { padding: .25rem .6rem; font-size: .85rem; }

/* A stat tile that is a link. The chassis styles .admin-stat as a block; these
   are anchors, so they need the text-decoration and colour reset explicitly or
   every number renders underlined and blue. */
.admin-stat { display: block; text-decoration: none; color: inherit; background: var(--color-bg-alt); border: 1px solid var(--color-border); border-radius: 10px; padding: .9rem 1rem; }
.admin-stat:hover { border-color: var(--color-border-strong); }
.admin-stat__n { display: block; font-family: var(--font-display); font-size: 1.75rem; line-height: 1.1; }
.admin-stat__l { display: block; font-size: .85rem; color: var(--color-text-muted); }
.admin-stat.is-attention { border-color: var(--color-primary); box-shadow: inset 0 0 0 1px var(--color-primary); }
.admin-stat.is-attention .admin-stat__n { color: var(--color-primary); }

.admin-toolbar { display: flex; gap: .3rem; flex-wrap: wrap; margin-bottom: .4rem; }

/* Per-platform social captions, side by side. They are three different pieces
   of copy, not one post with toggles — collapsing them would throw away the
   thing being paid for. */
.social-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(18rem, 1fr)); gap: 1rem; }
.social-col__head { display: flex; justify-content: space-between; align-items: baseline; gap: .5rem; font-weight: 500; margin-bottom: .25rem; }
.social-col__count { font-size: .78rem; color: var(--color-text-muted); font-variant-numeric: tabular-nums; }
.social-col__count.is-over { color: var(--color-danger); font-weight: 600; }
.social-draft { margin-bottom: 1.5rem; }

/* Social Media Engine: the write form and the post cards. */
.social-channels { border: 0; padding: 0; margin: 0; display: grid; gap: .4rem; }
.social-channels legend { font-weight: 500; margin-bottom: .35rem; padding: 0; }
.social-channel { display: flex; align-items: center; gap: .6rem; font-weight: 400; }
/* The chassis gives every input width:100%. A checkbox inherits it and centres
   itself in a full-width box, pushing its label off to the right. */
.social-channel input[type="checkbox"] { width: auto; flex: none; margin: 0; }
.social-own > summary { cursor: pointer; font-weight: 500; }
.social-own[open] > summary { margin-bottom: .5rem; }
.social-thumb { display: block; border-radius: 8px; margin-bottom: .5rem; height: auto; }
.social-post { display: grid; gap: 1rem; }
@media (min-width: 48rem) { .social-post { grid-template-columns: 12rem minmax(0, 1fr); } }
.social-post__img { width: 100%; max-width: 12rem; height: auto; border-radius: 8px; object-fit: cover; }
.social-post__meta { display: flex; flex-wrap: wrap; gap: .4rem; align-items: center; margin: 0 0 .6rem; }
.social-post__label { font-weight: 600; margin: .6rem 0 .15rem; font-size: .85rem; }
.social-post__text { margin: 0 0 .4rem; max-width: 65ch; overflow-wrap: anywhere; }
.social-post__by { font-size: .85rem; margin: .4rem 0 0; }
.social-inline-form { display: inline; margin: 0; }
.social-row-actions { white-space: nowrap; }
.social-row-actions .btn + .social-inline-form { margin-left: .35rem; }
/* The blog fields sit in a fieldset the chassis gives display:grid, which
   beats the browser's own [hidden]. Say it again with higher specificity or
   the fields never hide. */
.social-blog[hidden] { display: none; }
.social-blog { border: 1px solid var(--color-border); border-radius: 10px; padding: 1rem; margin: 0; display: grid; gap: 1rem; }
.social-blog legend { font-weight: 500; padding: 0 .35rem; }

.social-photos { list-style: none; margin: 0 0 .75rem; padding: 0; display: flex; flex-wrap: wrap; gap: .75rem; }
.social-photos li { display: grid; gap: .25rem; font-size: .85rem; }
.social-photos img { width: 120px; height: 90px; object-fit: cover; border-radius: 6px; }
.social-photos label { display: flex; gap: .35rem; align-items: center; font-weight: 400; }
.social-photos input { width: auto; margin: 0; }

/* Write form beside its preview on a wide screen, stacked on a narrow one. */
.social-compose { display: grid; gap: 1.5rem; margin-bottom: 1.5rem; }
@media (min-width: 80rem) {
  .social-compose { grid-template-columns: minmax(0, 1.25fr) minmax(0, 1fr); align-items: start; }
  .social-compose__preview { position: sticky; top: 1rem; max-height: calc(100vh - 2rem); overflow: auto; }
}
.social-compose .admin-card + .admin-card { margin-top: 0; }

/* PREVIEWS. A plain, neutral mock of each app's post: a header with the
   account, the words cut where the app cuts them, the photo or carousel. It is
   not a pixel copy of any app and uses none of their marks, only their names.
   The frame is white in both themes, because every app's feed is. */
.pv-row { display: grid; gap: 1rem; grid-template-columns: repeat(auto-fill, minmax(16rem, 1fr)); align-items: start; }
.pv-stack { display: grid; gap: 1.25rem; }
.pv { margin: 0; }
.pv__label { font-size: .78rem; font-weight: 600; letter-spacing: .04em; text-transform: uppercase; color: var(--color-text-muted); margin: 0 0 .35rem; }
.pv__frame { background: #fff; color: #1c1e21; border: 1px solid #dadde1; border-radius: 10px; overflow: hidden; max-width: 30rem; }
.pv__head { display: flex; gap: .6rem; align-items: center; padding: .7rem .8rem; }
.pv__head div { display: grid; line-height: 1.25; }
.pv__head strong { font-size: .92rem; }
.pv__head span { font-size: .78rem; color: #595c60; }
.pv__avatar { width: 36px; height: 36px; border-radius: 50%; object-fit: cover; background: #0000fe; flex: none; }
.pv--linkedin .pv__avatar { border-radius: 4px; }
.pv__text { margin: 0; padding: 0 .8rem .75rem; font-size: .92rem; line-height: 1.4; overflow-wrap: anywhere; max-width: none; }
.pv--instagram .pv__text { padding-top: .6rem; }
.pv__more { color: #595c60; font-weight: 500; }
.pv__one img { display: block; width: 100%; height: auto; max-height: 32rem; object-fit: cover; }
.pv__grid { display: grid; grid-template-columns: 1fr 1fr; gap: 2px; }
.pv__grid div { position: relative; aspect-ratio: 1; overflow: hidden; }
.pv__grid img { width: 100%; height: 100%; object-fit: cover; display: block; }
.pv__grid--3 div:first-child { grid-column: 1 / -1; aspect-ratio: 2; }
.pv__plus { position: absolute; inset: 0; display: grid; place-items: center; background: rgb(0 0 0 / .45); color: #fff; font-size: 1.6rem; font-weight: 600; }
.pv__ig { position: relative; overflow: hidden; background: #efefef; }
.pv__ig img { width: 100%; height: 100%; object-fit: cover; display: block; }
.pv__count { position: absolute; top: .6rem; right: .6rem; background: rgb(0 0 0 / .65); color: #fff; font-size: .75rem; border-radius: 999px; padding: .1rem .5rem; }
.pv__dots { display: flex; justify-content: center; gap: 4px; padding: .5rem 0 0; }
.pv__dots i { width: 6px; height: 6px; border-radius: 50%; background: #c7c7c7; }
.pv__dots i:first-child { background: #0000fe; }
.pv--blog .pv__frame { color: var(--color-text); background: var(--color-bg-alt); border-color: var(--color-border); }
.pv--blog .pv__more { color: var(--color-text-muted); }
.pv--blog .pv__one img { max-height: 12rem; }
.pv__blog-title { font-family: var(--font-display); font-size: 1.15rem; margin: .75rem .8rem .35rem; }
.social-post__meta { margin-bottom: .75rem; }

/* ---------------------------------------------------------------------------
   SOCIAL MEDIA ENGINE, CALENDAR FIRST (2026-10-21)

   The month is the home screen; writing and reading a post happen in a panel
   over it (.sm-drawer). The .social-* rules above belong to the screen this
   replaced and are no longer used by admin/social.php.

   Status colours are mixed from the theme's own blue, success and danger, so
   they follow dark mode with everything else. The network marks (.sm-ico) are
   only on the channel buttons and the calendar, to tell the channels apart at a
   glance; the preview frames still carry none.
   --------------------------------------------------------------------------- */
.admin-main:has(.sm-month) { max-width: 90rem; }
.sm-head { display: flex; flex-wrap: wrap; align-items: flex-end; justify-content: space-between; gap: var(--sp-3); }
.sm-head p { margin: .2rem 0 0; font-size: .9rem; }
.sm-head__acts { display: flex; flex-wrap: wrap; gap: var(--sp-2); }
.sm-ico { width: 18px; height: 18px; flex: none; display: inline-block; vertical-align: middle; }
.sm-ico--sm { width: 14px; height: 14px; }
.sm-ico--xs { width: 12px; height: 12px; }
.sm-inline-form { display: inline; margin: 0; }
.sm-btn-text { border-color: transparent; background: none; }
.sm-btn-danger { color: var(--color-danger); }
.sm-note { margin: 0 0 var(--sp-4); }

.sm-pill { display: inline-flex; align-items: center; gap: .3rem; font-size: .76rem; font-weight: 600; border-radius: 999px; padding: .1rem .55rem; white-space: nowrap; text-decoration: none; }
.sm-pill--scheduled { background: color-mix(in srgb, var(--color-primary) 12%, transparent); color: var(--color-accent-text-tint); }
.sm-pill--sent      { background: color-mix(in srgb, var(--color-success) 16%, transparent); color: var(--color-text); }
.sm-pill--failed    { background: color-mix(in srgb, var(--color-danger) 14%, transparent); color: var(--color-text); }
.sm-pill--draft     { background: var(--color-bg-sunk); color: var(--color-text-muted); }
a.sm-pill:hover { text-decoration: underline; }

.sm-alert { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--sp-2) var(--sp-4);
  background: color-mix(in srgb, var(--color-danger) 10%, var(--color-bg-alt)); border: 1px solid color-mix(in srgb, var(--color-danger) 35%, transparent);
  border-radius: var(--radius-sm); padding: var(--sp-3) var(--sp-4); margin-bottom: var(--sp-4); font-size: .92rem; }
.sm-undo { display: flex; align-items: center; gap: var(--sp-3); margin: calc(-1 * var(--sp-2)) 0 var(--sp-4); font-size: .9rem; color: var(--color-text-muted); }

/* Calendar toolbar */
.sm-calbar { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-2) var(--sp-3); margin-bottom: var(--sp-3); }
.sm-calbar h2 { font-family: var(--font-display); font-size: 1.35rem; margin: 0; min-width: 9.5rem; }
.sm-calbar__nav { display: inline-flex; gap: .25rem; }
.sm-iconbtn { width: 36px; height: 36px; display: inline-grid; place-items: center; border: 1px solid var(--color-border); border-radius: var(--radius-sm);
  background: var(--color-bg-alt); color: var(--color-text); font-size: 1.15rem; line-height: 1; text-decoration: none; }
.sm-iconbtn:hover { background: var(--color-bg-sunk); text-decoration: none; }
.sm-toggle { display: inline-flex; margin-left: auto; border: 1px solid var(--color-border); border-radius: var(--radius-sm); overflow: hidden; }
.sm-toggle a { padding: .4rem .85rem; font-weight: 500; font-size: .88rem; color: var(--color-text); background: var(--color-bg-alt); text-decoration: none; }
.sm-toggle a + a { border-left: 1px solid var(--color-border); }
.sm-toggle a[aria-current="true"] { background: var(--color-primary); color: var(--color-on-accent); }

/* The month */
.sm-month { background: var(--color-bg-alt); border: 1px solid var(--color-border); border-radius: var(--radius-md); overflow: hidden; }
.sm-month__dow, .sm-month__grid { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); }
.sm-month__dow { background: var(--color-bg-sunk); border-bottom: 1px solid var(--color-border); }
.sm-month__dow span { padding: .45rem .5rem; font-size: .7rem; font-weight: 700; letter-spacing: .07em; text-transform: uppercase; color: var(--color-text-muted); }
.sm-day { position: relative; min-height: 7.25rem; padding: .35rem .35rem .5rem; display: flex; flex-direction: column; gap: .25rem; min-width: 0;
  border-right: 1px solid var(--color-border); border-bottom: 1px solid var(--color-border); cursor: pointer; }
.sm-day:nth-child(7n) { border-right: 0; }
.sm-day:hover { background: color-mix(in srgb, var(--color-primary) 3%, var(--color-bg-alt)); }
.sm-day.is-out { background: var(--color-bg); }
.sm-day.is-out .sm-day__num { color: var(--color-text-muted); }
.sm-day.is-past { cursor: default; }
.sm-day.is-over { background: var(--color-primary-soft); box-shadow: inset 0 0 0 2px var(--color-primary); }
.sm-day__top { display: flex; align-items: center; justify-content: space-between; }
.sm-day__num { width: 26px; height: 26px; display: grid; place-items: center; border-radius: 50%; font-size: .82rem; font-weight: 600; }
.sm-day.is-today .sm-day__num { background: var(--color-primary); color: var(--color-on-accent); }
.sm-day__add { opacity: 0; width: 24px; height: 24px; display: grid; place-items: center; border-radius: var(--radius-sm); font-weight: 700; line-height: 1;
  background: var(--color-primary-soft); color: var(--color-accent-text-tint); text-decoration: none; }
.sm-day:hover .sm-day__add, .sm-day__add:focus-visible { opacity: 1; text-decoration: none; }
@media (hover: none) { .sm-day__add { opacity: 1; } }
.sm-chip { display: flex; align-items: center; gap: .3rem; min-width: 0; border-radius: var(--radius-sm); padding: .15rem .3rem .15rem .15rem;
  font-size: .76rem; line-height: 1.2; font-weight: 600; text-decoration: none; }
.sm-chip:hover { text-decoration: none; filter: brightness(.97); }
.sm-chip__img { width: 22px; height: 22px; border-radius: 4px; object-fit: cover; flex: none; }
.sm-chip__t { white-space: nowrap; }
.sm-chip__ch { display: inline-flex; gap: 2px; margin-left: auto; flex: none; }
.sm-chip--scheduled { background: color-mix(in srgb, var(--color-primary) 11%, var(--color-bg-alt)); color: var(--color-accent-text-tint); }
.sm-chip--scheduled[draggable="true"] { cursor: grab; }
.sm-chip--sent { background: color-mix(in srgb, var(--color-success) 14%, var(--color-bg-alt)); color: var(--color-text); }
.sm-chip--failed { background: color-mix(in srgb, var(--color-danger) 13%, var(--color-bg-alt)); color: var(--color-text); }
.sm-noimg { display: inline-grid; place-items: center; background: var(--color-bg-sunk); color: var(--color-text-muted); font-size: .65rem; font-weight: 600; }
.sm-chip .sm-noimg { width: 22px; height: 22px; border-radius: 4px; flex: none; }
.sm-more { font-size: .74rem; font-weight: 600; padding: 0 .25rem; }
.sm-legend { display: flex; flex-wrap: wrap; gap: .4rem 1rem; margin-top: var(--sp-3); font-size: .8rem; color: var(--color-text-muted); }
.sm-legend span { display: inline-flex; align-items: center; gap: .4rem; }
.sm-legend i { width: 10px; height: 10px; border-radius: 3px; }
.sm-legend--scheduled { background: color-mix(in srgb, var(--color-primary) 30%, var(--color-bg-alt)); }
.sm-legend--sent { background: color-mix(in srgb, var(--color-success) 40%, var(--color-bg-alt)); }
.sm-legend--failed { background: color-mix(in srgb, var(--color-danger) 40%, var(--color-bg-alt)); }
@media (max-width: 45rem) {
  .sm-day { min-height: 4.75rem; padding: .2rem; }
  .sm-chip { justify-content: center; padding: .1rem; }
  .sm-chip__t, .sm-chip__ch { display: none; }
  .sm-chip__img, .sm-chip .sm-noimg { width: 100%; height: 26px; }
  .sm-toggle { margin-left: 0; }
}

/* Lists: the agenda, a day, the blog picker */
.sm-agenda { display: grid; gap: var(--sp-5); }
.sm-agenda h3 { font-size: .8rem; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: var(--color-text-muted); margin: 0 0 .4rem; }
.sm-row { display: flex; align-items: center; gap: var(--sp-3); min-width: 0; background: var(--color-bg-alt); border: 1px solid var(--color-border);
  border-radius: var(--radius-md); padding: .5rem .75rem .5rem .5rem; color: var(--color-text); text-decoration: none; }
.sm-row + .sm-row { margin-top: .4rem; }
.sm-row:hover { border-color: var(--color-border-strong); text-decoration: none; }
.sm-row__img { width: 52px; height: 52px; border-radius: 7px; object-fit: cover; flex: none; }
.sm-row__body { min-width: 0; flex: 1; display: grid; gap: .2rem; }
.sm-row__cap { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.sm-row__meta { display: flex; flex-wrap: wrap; align-items: center; gap: .4rem; font-size: .8rem; color: var(--color-text-muted); }
.sm-row__ch { display: inline-flex; gap: 3px; }

/* Drafts */
.sm-cards { display: grid; gap: var(--sp-3); grid-template-columns: repeat(auto-fill, minmax(min(100%, 15rem), 1fr)); }
.sm-dcard { background: var(--color-bg-alt); border: 1px solid var(--color-border); border-radius: var(--radius-md); overflow: hidden; display: flex; flex-direction: column; }
.sm-dcard__img { aspect-ratio: 16 / 9; display: grid; place-items: center; background: var(--color-bg-sunk); color: var(--color-text-muted); font-size: .85rem; }
.sm-dcard__img img { width: 100%; height: 100%; object-fit: cover; display: block; }
.sm-dcard__b { padding: .65rem .8rem .8rem; display: grid; gap: .5rem; flex: 1; align-content: space-between; justify-items: start; }
.sm-dcard__b p { margin: 0; font-size: .9rem; overflow-wrap: anywhere; }
.sm-dcard__act { display: flex; flex-wrap: wrap; gap: .4rem; align-items: start; }

.sm-ctable__ch { display: inline-flex; align-items: center; gap: .6rem; font-weight: 600; }
.sm-ctable__ch .sm-ico { width: 24px; height: 24px; }

/* Two-step delete / stop, no confirm() dialog */
.sm-confirm { display: inline-block; }
.sm-confirm > summary { list-style: none; cursor: pointer; }
.sm-confirm > summary::-webkit-details-marker { display: none; }
.sm-confirm[open] > summary { display: none; }
.sm-confirm__box { display: flex; flex-wrap: wrap; align-items: center; gap: .5rem; padding: .5rem .7rem; font-size: .88rem;
  background: color-mix(in srgb, var(--color-danger) 8%, var(--color-bg-alt)); border: 1px solid color-mix(in srgb, var(--color-danger) 30%, transparent); border-radius: var(--radius-sm); }

/* The panel over the calendar */
.sm-scrim { position: fixed; inset: 0; z-index: 90; background: rgb(8 10 16 / .4); }
.sm-drawer { position: fixed; top: 0; right: 0; bottom: 0; z-index: 91; width: min(60rem, 100%); background: var(--color-bg-alt);
  box-shadow: -14px 0 40px rgb(0 0 0 / .2); overflow-y: auto; overscroll-behavior: contain; }
.sm-drawer--narrow { width: min(34rem, 100%); }
.sm-drawer__head { position: sticky; top: 0; z-index: 2; display: flex; align-items: center; justify-content: space-between; gap: var(--sp-3);
  padding: var(--sp-3) var(--sp-5); background: var(--color-bg-alt); border-bottom: 1px solid var(--color-border); }
.sm-drawer__head h2 { font-family: var(--font-display); font-size: 1.25rem; margin: 0; }
.sm-drawer__head h2:focus { outline: none; }   /* focused by script on open, for screen readers; not a control */
.sm-drawer__body { padding: var(--sp-5) var(--sp-5) var(--sp-8); }
@media (prefers-reduced-motion: no-preference) { .sm-drawer { animation: sm-slide .2s var(--ease-out); } }
@keyframes sm-slide { from { transform: translateX(1.5rem); opacity: .6; } }
body:has(.sm-drawer) { overflow: hidden; }

.sm-detail__meta { display: flex; flex-wrap: wrap; align-items: center; gap: .5rem; margin-bottom: var(--sp-3); font-size: .85rem; }
.sm-results { display: flex; flex-wrap: wrap; gap: .4rem; margin-bottom: var(--sp-4); }
.sm-detail__acts { margin-top: var(--sp-5); align-items: start; }
.sm-pvtabs { display: flex; flex-wrap: wrap; gap: .3rem; margin-bottom: .5rem; }
.sm-pvtabs:empty { display: none; }
.sm-pvtabs button { display: inline-flex; align-items: center; gap: .35rem; border: 1px solid var(--color-border); background: var(--color-bg-alt);
  color: var(--color-text); border-radius: var(--radius-sm); padding: .3rem .6rem; font: inherit; font-size: .82rem; cursor: pointer; }
.sm-pvtabs button[aria-pressed="true"] { border-color: var(--color-text); box-shadow: inset 0 0 0 1px var(--color-text); font-weight: 600; }

/* The write panel */
.sm-compose { display: grid; gap: var(--sp-6); }
@media (min-width: 52rem) {
  .sm-compose { grid-template-columns: minmax(0, 1.1fr) minmax(0, .9fr); align-items: start; }
  .sm-compose__preview { position: sticky; top: 4.5rem; }
}
.sm-compose__form { display: block; }
.sm-fld { border: 0; padding: 0; margin: 0 0 var(--sp-5); min-width: 0; }
.sm-fld__h { display: flex; flex-wrap: wrap; justify-content: space-between; align-items: baseline; gap: .5rem; width: 100%;
  font-family: var(--font-sans); font-size: .95rem; font-weight: 600; margin: 0 0 .5rem; padding: 0; }
.sm-fld__h label { font-weight: 600; }
.sm-count { font-size: .76rem; font-weight: 400; color: var(--color-text-muted); font-variant-numeric: tabular-nums; }
.sm-count.is-over { color: var(--color-danger); font-weight: 600; }
.sm-photos { list-style: none; margin: 0 0 .5rem; padding: 0; display: flex; flex-wrap: wrap; gap: .6rem; }
.sm-photos li { display: grid; gap: .2rem; font-size: .8rem; align-content: start; }
.sm-photos img { width: 104px; height: 80px; object-fit: cover; border-radius: var(--radius-sm); }
.sm-photos label { display: flex; gap: .3rem; align-items: center; font-weight: 400; }
.sm-photos input[type="checkbox"], .sm-photos input[type="radio"] { width: auto; margin: 0; }
.sm-photos__add { position: relative; }
.sm-photos__add label { width: 104px; height: 80px; display: grid; place-items: center; text-align: center; border: 2px dashed var(--color-border-strong);
  border-radius: var(--radius-sm); color: var(--color-text-muted); font-weight: 600; font-size: .85rem; cursor: pointer; line-height: 1.2; }
.sm-photos__add label:hover { border-color: var(--color-primary); color: var(--color-accent-text-tint); }
.sm-photos__add input { position: absolute; width: 1px; height: 1px; opacity: 0; }
.sm-photos__add:focus-within label { outline: 2px solid var(--focus-ring); outline-offset: 2px; }
.sm-photos__new img { outline: 2px solid var(--color-primary); outline-offset: -2px; }
.sm-alt { margin-top: var(--sp-3); }
.sm-wtabs { display: flex; flex-wrap: wrap; gap: .3rem; margin-bottom: .4rem; }
.sm-wtabs button { display: inline-flex; align-items: center; gap: .3rem; border: 1px solid var(--color-border); background: var(--color-bg-alt); color: var(--color-text);
  border-radius: 999px; padding: .2rem .7rem; font: inherit; font-size: .8rem; cursor: pointer; }
.sm-wtabs button[aria-pressed="true"] { background: var(--color-text); border-color: var(--color-text); color: var(--color-bg); }
.sm-wtabs button.has-own::after { content: ""; width: 6px; height: 6px; border-radius: 50%; background: var(--color-primary); }
.sm-chans { display: flex; flex-wrap: wrap; gap: .5rem; }
.sm-ch { position: relative; display: inline-flex; align-items: center; gap: .55rem; padding: .45rem .8rem .45rem .6rem; cursor: pointer;
  border: 1.5px solid var(--color-border); border-radius: var(--radius-sm); background: var(--color-bg-alt); font-weight: 600; font-size: .88rem; line-height: 1.2; }
.sm-ch small { display: block; font-weight: 400; font-size: .74rem; color: var(--color-text-muted); }
.sm-ch input { position: absolute; opacity: 0; width: 1px; height: 1px; margin: 0; }
.sm-ch:has(input:checked) { border-color: var(--color-primary); background: var(--color-primary-soft); }
.sm-ch:has(input:not(:checked)) .sm-ico { filter: grayscale(1); opacity: .45; }
.sm-ch:has(input:focus-visible) { outline: 2px solid var(--focus-ring); outline-offset: 2px; }
.sm-ch:has(input:disabled) { opacity: .55; cursor: not-allowed; }
.sm-blog { display: grid; gap: var(--sp-3); margin-top: var(--sp-3); padding: var(--sp-4); border: 1px solid var(--color-border); border-radius: var(--radius-md); }
.sm-blog[hidden] { display: none; }
.sm-quick { display: flex; flex-wrap: wrap; gap: .35rem; margin-bottom: .6rem; }
.sm-quick button { border: 1px solid var(--color-border); background: var(--color-bg-alt); color: var(--color-text); border-radius: 999px;
  padding: .3rem .8rem; font: inherit; font-size: .84rem; cursor: pointer; }
.sm-quick button[aria-pressed="true"] { background: var(--color-primary); border-color: var(--color-primary); color: var(--color-on-accent); }
.sm-dt { display: grid; grid-template-columns: minmax(0, 1.3fr) minmax(0, 1fr); gap: var(--sp-3); }
.sm-dt .admin-field { margin: 0; }
.sm-whenline { margin: .5rem 0 0; font-size: .88rem; font-weight: 500; }
.sm-compose__acts { position: sticky; bottom: 0; z-index: 1; background: var(--color-bg-alt); padding: var(--sp-3) 0; border-top: 1px solid var(--color-border); }

/* ---------------------------------------------------------------------------
   COMING SOON — the three automation tabs

   Bulk Emailer, Social Media Engine and Lead Generator all run on demo fixtures
   until each product is connected to CATO's own n8n. The fixtures stay on
   screen, blurred, so the shape of the screen is still visible while nothing on
   it can be read as real or acted on.

   THE BLUR IS THE VISIBLE HALF OF THE GUARD, NOT THE GUARD. The mask carries
   inert, which takes the whole subtree out of the tab order and out of the
   accessibility tree, so a keyboard or screen reader user cannot reach a
   control that does nothing. pointer-events and user-select close the mouse
   half: blurred text is still selectable, and selected demo text can be copied
   and mistaken for real data.
   --------------------------------------------------------------------------- */
.admin-soon { position: relative; }
.admin-soon__mask { filter: blur(6px); pointer-events: none; user-select: none; }
/* An engine with no inert support still gets the visual state, and the two
   properties above still block the mouse. */
.admin-soon__mask[inert] { opacity: .75; }

.admin-soon__note {
  position: absolute; inset-inline: 0; top: clamp(1rem, 5vw, 3.5rem);
  z-index: 2; margin-inline: auto; max-width: 32rem;
  background: var(--color-bg-alt);
  border: 1px solid var(--color-border); border-top: 3px solid var(--color-primary);
  border-radius: 12px; padding: 1.5rem; text-align: center;
  box-shadow: 0 18px 40px rgb(0 0 0 / .18);
}
/* --color-accent-text-tint, not the brand blue: theme.css records plain blue on
   a soft tint at 4.18:1, under AA. Same call as .admin-side a.is-active. */
.admin-soon__eyebrow {
  display: inline-block; margin-bottom: .4rem;
  font-size: .6875rem; font-weight: 800; letter-spacing: .08em;
  text-transform: uppercase; color: var(--color-accent-text-tint);
}
.admin-soon__note h2 { margin: 0 0 .4rem; font-size: 1.25rem; }
.admin-soon__note p { margin: 0; max-width: none; color: var(--color-text-muted); }

/* --- Framed staff tool (admin/emailer.php) ---------------------------------
   The Bulk Emailer's own staff page, framed as-is. It scrolls inside the frame,
   so the frame takes the height of the screen below the admin header rather
   than a fixed guess; min-height keeps it usable on a short laptop screen. */
.admin-embed {
  margin-top: 1rem; border: 1px solid var(--color-border); border-radius: 12px;
  overflow: hidden; background: #f4f6f8;
}
.admin-embed iframe {
  display: block; width: 100%; border: 0;
  height: calc(100vh - 13rem); min-height: 40rem;
}

/* --- Logo ------------------------------------------------------------------
   The width/height attributes carry the intrinsic size (300x171) so the browser
   reserves space and there is no layout shift. CSS then caps the RENDERED size.
   height:auto is required alongside a width cap, or the aspect ratio is ignored
   and the logo squashes. */
.brand__logo { max-height: 52px; width: auto; height: auto; display: block; }
.site-footer .brand__logo { max-height: 46px; }

/* Spec repeater rows on the product editor. */
.admin-specs__row { display: grid; grid-template-columns: 1fr 1fr auto; gap: .5rem; align-items: start; margin-bottom: .5rem; }
@media (max-width: 40rem) { .admin-specs__row { grid-template-columns: 1fr; } }
.admin-gallery { display: flex; flex-wrap: wrap; gap: .75rem; margin-bottom: 1rem; }
.admin-gallery__item { display: block; font-size: .78rem; text-align: center; }
.admin-gallery__item img { display: block; border-radius: 6px; border: 1px solid var(--color-border); }

/* ---------------------------------------------------------------------------
   ADMIN SHELL — the section nav as a column beside the page, not a row above it

   Replaces the single wrapping run of .admin-nav. Fifteen links in one row wrapped
   to three lines and gave the four sections equal visual weight, so "Leads" read
   as more catalog admin. A column with the section name above its pages says what
   job a link belongs to before you read the link.

   The .admin-nav rules in shop.css (~L416-431) are unused on this site now and
   left in place deliberately: they are chassis lineage shared with the ecommerce
   template, not CATO's to delete.
   --------------------------------------------------------------------------- */
.admin-side { background: var(--color-bg); border-bottom: 1px solid var(--color-border); }

/* The phone control. 44px, and it names the page you are on so the menu can stay
   shut and still answer "where am I". */
.admin-side__toggle {
  display: flex; align-items: center; gap: var(--sp-2);
  min-height: 44px; padding: var(--sp-2) var(--sp-5);
  font-weight: 700; font-size: .9375rem;
  cursor: pointer; list-style: none;
}
.admin-side__toggle::-webkit-details-marker { display: none; }
.admin-side__toggle::before {
  content: ""; flex: none; width: .5em; height: .5em;
  border-right: 2px solid currentColor; border-bottom: 2px solid currentColor;
  transform: rotate(45deg); margin-bottom: .2em;
}
.admin-side__disclosure[open] > .admin-side__toggle::before { transform: rotate(-135deg); margin-bottom: -.1em; }
.admin-side__toggle:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: -2px; }
.admin-side__here { color: var(--color-text-muted); font-weight: 600; }
.admin-side__here::before { content: "\00b7 "; }

.admin-side__panel { padding-bottom: var(--sp-3); }

/* max-width: none because the chassis caps <p> at the reading measure, which
   would otherwise wrap "Gallery categories" onto two lines. */
.admin-side__group {
  margin: var(--sp-4) 0 var(--sp-1); padding: 0 var(--sp-5); max-width: none;
  font-size: .6875rem; font-weight: 800;
  text-transform: uppercase; letter-spacing: .08em;
  color: var(--color-text-muted);
}
.admin-side__section.is-current > .admin-side__group { color: var(--color-text); }

.admin-side__list { list-style: none; margin: 0; padding: 0; }
.admin-side a {
  display: flex; align-items: center;
  min-height: 44px; padding: var(--sp-2) var(--sp-5);
  color: var(--color-text); font-weight: 600; font-size: .9375rem;
  border-left: 3px solid transparent;
}
.admin-side a:hover { text-decoration: none; background: var(--color-bg-alt); }
/* --color-accent-text-tint, not the plain brand blue: theme.css records that blue
   on --color-primary-soft measures 4.18:1 and drops under AA. Same reason
   shop.css uses the tint for .admin-nav a.is-active. */
.admin-side a.is-active {
  background: var(--color-primary-soft);
  border-left-color: var(--color-primary);
  color: var(--color-accent-text-tint);
}

@media (min-width: 60rem) {
  /* minmax(0, 1fr), not 1fr: a grid track's min-content floor is what lets a wide
     .admin-table shove the whole page sideways instead of scrolling inside its
     own .admin-table-wrap. */
  .admin-shell { display: grid; grid-template-columns: 15rem minmax(0, 1fr); }

  .admin-side {
    border-bottom: 0;
    border-right: 1px solid var(--color-border);
    padding-bottom: var(--sp-10);
  }

  /* Permanently open above this width. TWO rules, because two generations of
     engine hide closed <details> content differently: older ones display:none the
     non-summary children, which is overridable; Chrome 131+, Safari 18.4+ and
     Firefox 139+ move it into ::details-content with content-visibility:hidden,
     which display alone cannot undo. Every engine in the field is one or the
     other, and one that cannot parse ::details-content drops only that ruleset. */
  .admin-side__disclosure > .admin-side__toggle { display: none; }
  .admin-side__disclosure > .admin-side__panel  { display: block; }
  .admin-side__disclosure::details-content { content-visibility: visible; display: block; }

  /* Left-aligned in its own track, still capped. Centring the content between a
     fixed sidebar and the window edge reads as a mistake. */
  .admin-main { margin-inline: 0; padding-inline: var(--sp-8); }
}


/* ============================================================================
   THE APPROVED REBUILD LAYER
   ----------------------------------------------------------------------------
   Everything below this line is the port of

       Website Upgrade\html-rebuild\cato-custom-css.css

   the stylesheet the client signed off on in June. It is APPROVED DESIGN WORK.
   Restyle it only on a real instruction, not on taste.

   Four things changed on the way in, and nothing else:

   1. Its local tokens are namespaced --cato-* and aliased onto theme.css. The
      original declared literal hex because a YOOtheme Customizer has no token
      layer underneath it. Left un-namespaced, --shadow-sm / --shadow-lg /
      --radius-lg would have silently re-shadowed every chassis component
      nested inside .cato-page.
   2. UIkit coupling removed - this site does not ship UIkit.
      .uk-slideshow-items -> .cato-hero__items, .uk-active -> .is-active
      (which is what the rest of this build already uses), [uk-icon] ->
      .cato-icon (inline SVG, no icon font).
   3. Section 18 (WPForms/Forminator restyling) dropped. That form does not
      exist here; contact.php uses the chassis form, which is already styled
      and already CSRF-guarded.
   4. Section 19 (YOOtheme Dynamic Content post grids) dropped. /what-we-do
      renders through Spark's own .blog-card markup instead of nudging YT's
      generated cards, so the selectors had nothing to hook.

   Section numbering below is the ORIGINAL numbering, gaps included, so a
   reference back to the approved sheet still lands on the right block.
   ============================================================================ */

/* =====================================================================
   CATO - Homepage Custom CSS  (Option A: showroom-first / editorial)
   Paste into: YT Customizer > Settings > Custom Code > Custom CSS
   Pairs with: homepage.html (one YT HTML element)

   SECTIONS COVERED:
     1.  Tokens
     2.  Layout primitives
     3.  Typography
     4.  Buttons
     5.  HERO - full-bleed showroom + centered overlay
     6.  STATS - dark 4-up band
     7.  SERVICES - frosted glass cards
     8.  ROYAL exclusive callout
     9.  BRANDS - logo grid
     10. REVIEWS
     11. NTEA - diamond-plate background band
     12. CONTACT - dark + map
     13. Reveal-on-scroll

   NOTE: no @import. Oswald / Roboto / Rubik are loaded by the YT
   Customizer (see cato-style.json). YT's Custom CSS sanitizer
   rejects @import and stops parsing the rest of the file when it
   sees one - that's what broke the previous paste.
   ===================================================================== */


/* ------------------------------------------------------------------ */
/* 1. TOKENS                                                          */
/* ------------------------------------------------------------------ */
.cato-page {
  /* PORT NOTE. The approved rebuild declared these as literal hex, because it
     lived in a YOOtheme Customizer with no token layer underneath it. Here they
     are ALIASES onto theme.css, so the palette has exactly one home and the
     dark-mode block in theme.css reaches this design for free. The values below
     the alias in a comment are what the approved sheet had, for reference.

     Namespaced --cato-* on purpose: --shadow-sm, --shadow-lg and --radius-lg
     already exist in theme.css, and redefining them here would silently
     re-shadow every chassis component nested inside .cato-page. */
  --cato-bg:        var(--color-bg);            /* was #FAFAF7 */
  --cato-surface:   var(--color-bg-alt);        /* was #FFFFFF */
  --cato-ink:       var(--color-text);          /* was #080808 brand black */
  --cato-ink-2:     var(--color-text-muted);    /* was #5C5C5C */
  --cato-rule:      var(--color-border);        /* was #E6E4DE */

  /* Brand blue stays a hard alias of the brand token, not of --color-accent-text.
     The approved sheet is explicit that the brand is blue + black only, and that
     --hover is an alias of --brand rather than a second hue. Keep it that way:
     a CATO sale badge is blue, and that is deliberate, not a bug. */
  --cato-brand:     var(--brand-primary);       /* #0000FE */
  --cato-brand-ink: var(--brand-on-primary);
  --cato-hover:     var(--brand-primary);

  --cato-shadow-sm: 0 2px 8px rgba(0,0,0,0.04);
  --cato-shadow:    0 8px 28px rgba(0,0,0,0.08);
  --cato-shadow-lg: 0 18px 48px rgba(0,0,0,0.14);
  --cato-radius:    8px;
  --cato-radius-lg: 16px;
  --cato-gutter:    24px;
  --cato-container: 1280px;

  background: var(--cato-bg);
  color: var(--cato-ink);
  font-family: var(--font-sans);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

/* Dark mode. The approved design is built on dark sections sitting ON a light
   page; in dark mode the page itself goes dark, so the "dark band" sections stop
   reading as bands. Lift their surface instead of leaving them black-on-black. */
/* Light-only since launch (2026-10-27): the OS-preference copy of this block
   was removed, so only an explicit data-theme="dark" (never set) reaches it. */
:root[data-theme="dark"] .cato-page {
  --cato-shadow-sm: 0 2px 8px rgba(0,0,0,0.35);
  --cato-shadow:    0 8px 28px rgba(0,0,0,0.45);
  --cato-shadow-lg: 0 18px 48px rgba(0,0,0,0.55);
}

.cato-page *,
.cato-page *::before,
.cato-page *::after { box-sizing: border-box; }


/* ------------------------------------------------------------------ */
/* 2. LAYOUT PRIMITIVES                                               */
/* ------------------------------------------------------------------ */
.cato-section {
  padding: 96px 0;
  position: relative;
}
.cato-section--tight { padding: 64px 0; }
.cato-section--bleed { padding: 0; }

/* Service-area hero band: subtle brand-blue wash + bottom hairline so the
   no-image centered hero reads as its own band above the off-white intro. */
.cato-hero-band {
  background: linear-gradient(180deg, rgba(0,0,254,0.07) 0%, rgba(0,0,254,0.02) 100%);
  border-bottom: 1px solid var(--cato-rule);
}
@media (max-width: 768px) {
  .cato-section { padding: 56px 0; }
}

.cato-container {
  width: 100%;
  max-width: var(--cato-container);
  margin: 0 auto;
  padding: 0 32px;
}
@media (max-width: 640px) {
  .cato-container { padding: 0 20px; }
}

.cato-section__head { max-width: 760px; margin: 0 0 56px 0; }
.cato-section__head--center {
  margin-left: auto;
  margin-right: auto;
  text-align: center;
}

/* Service-area city pages: center the "Our Home Base" intro so it matches the
   rest of the page. The base .cato-section__head is left-pinned at max-width:760px,
   which left this one section off to the side. Scoped to #sa-intro, reused on all 5
   city pages (Bryant/Benton/Bauxite/Conway/Little Rock), so one block fixes them all. */
#sa-intro .cato-section__head { margin-left: auto; margin-right: auto; text-align: center; }
#sa-intro .cato-eyebrow       { justify-content: center; }
#sa-intro .cato-display       { text-align: center; }
#sa-intro .cato-lead          { margin-left: auto; margin-right: auto; text-align: center; }


/* ------------------------------------------------------------------ */
/* 3. TYPOGRAPHY                                                      */
/* ------------------------------------------------------------------ */
.cato-eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 12px;
  margin: 0 0 20px 0;
  font-family: 'Rubik', 'Roboto', sans-serif;
  font-size: 12px;
  font-weight: 500;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--cato-ink-2);
}
.cato-eyebrow::before {
  content: '';
  display: block;
  width: 28px;
  height: 1px;
  background: var(--cato-brand);
}
.cato-eyebrow--center { justify-content: center; }
.cato-eyebrow--light {
  color: rgba(255,255,255,0.85);
}
.cato-eyebrow--light::before { background: var(--cato-hover); }

/* On mobile, stack the dash above the text so the bar lines up
   vertically (centered) with the eyebrow line, instead of sitting
   beside a single wrapping line. */
@media (max-width: 640px) {
  .cato-eyebrow--center {
    flex-direction: column;
    gap: 8px;
  }
}

.cato-display {
  margin: 0 0 20px 0;
  font-family: 'Oswald', 'Arial Narrow', sans-serif;
  font-weight: 600;
  font-size: clamp(36px, 5.4vw, 76px);
  line-height: 1.02;
  letter-spacing: -0.005em;
  color: var(--cato-ink);
  text-wrap: balance;
}
.cato-display em {
  font-style: normal;
  color: var(--cato-brand);
}
.cato-display--center  { text-align: center; }
.cato-display--lg      { font-size: clamp(44px, 7vw, 96px); }
.cato-display--inverse { color: #FFFFFF; }
.cato-display--inverse em { color: var(--cato-hover); }

.cato-lead {
  margin: 0 0 28px 0;
  font-family: 'Roboto', sans-serif;
  font-size: clamp(16px, 1.25vw, 19px);
  line-height: 1.55;
  color: var(--cato-ink);
  max-width: 56ch;
}
.cato-lead--muted   { color: var(--cato-ink-2); }
.cato-lead--inverse { color: rgba(255,255,255,0.92); }
.cato-lead--center  {
  margin-left: auto;
  margin-right: auto;
  text-align: center;
}

/* Generic link reset - EXCLUDE anything that paints its own background, so its
   explicit color rule wins.

   Without :not(.cato-btn), anchor links with class .cato-btn--primary inherit
   color from the parent (black on the light hero text zone) instead of the
   button's #FFFFFF. Same trap for ghost buttons - they'd inherit ink black
   instead of brand blue.

   .cato-chip and .cato-cathip are here for the SAME reason, and it is worth
   spelling out because the specificity is what makes it invisible: this
   selector is .cato-page a:not(.cato-btn) = (0,2,1), and .cato-chip.is-active
   = (0,2,0). The element rule tips it, so `color: inherit` silently beat the
   active chip's own white and painted it near-black on brand blue - 2.3:1,
   a WCAG AA failure, on the selected filter of every post listing. The chip
   defined the right colour the whole time; it just never won.

   ANY future component that is an <a> with its own background belongs in this
   exclusion list. */
.cato-page a:not(.cato-btn):not(.cato-chip):not(.cato-cathip) { color: inherit; text-decoration: none; }
.cato-page a:not(.cato-btn):not(.cato-chip):not(.cato-cathip):hover,
.cato-page a:not(.cato-btn):not(.cato-chip):not(.cato-cathip):focus-visible { color: var(--cato-hover); }


/* ------------------------------------------------------------------ */
/* 4. BUTTONS                                                         */
/* ------------------------------------------------------------------ */
.cato-btn {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 14px 24px;
  border-radius: var(--cato-radius);
  font-family: 'Oswald', sans-serif;
  font-size: 14px;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  cursor: pointer;
  transition: background 0.2s ease, color 0.2s ease, transform 0.2s ease, border-color 0.2s ease, box-shadow 0.2s ease;
  border: 1px solid transparent;
  white-space: nowrap;
  line-height: 1;
}
.cato-btn:focus-visible {
  outline: 2px solid var(--cato-hover);
  outline-offset: 3px;
}
/* Primary: blue bg + white text -> on hover, white bg + blue text (blue border throughout) */
.cato-btn--primary {
  background: var(--cato-brand);
  color: #FFFFFF;
  border-color: var(--cato-brand);
}
.cato-btn--primary:hover,
.cato-btn--primary:focus-visible {
  background: var(--cato-surface);
  color: var(--cato-brand);
  border-color: var(--cato-brand);
  transform: translateY(-1px);
  box-shadow: var(--cato-shadow);
}

/* Secondary (ghost): white bg + blue text -> on hover, blue bg + white text (mirror of primary) */
.cato-btn--ghost,
.cato-btn--ghost-inverse {
  background: var(--cato-surface);
  color: var(--cato-brand);
  border-color: var(--cato-brand);
}
.cato-btn--ghost:hover,
.cato-btn--ghost:focus-visible,
.cato-btn--ghost-inverse:hover,
.cato-btn--ghost-inverse:focus-visible {
  background: var(--cato-brand);
  color: #FFFFFF;
  border-color: var(--cato-brand);
  transform: translateY(-1px);
  box-shadow: var(--cato-shadow);
}
.cato-btn--text {
  padding: 6px 0;
  background: transparent;
  color: var(--cato-ink);
  letter-spacing: 0.06em;
  border-bottom: 1px solid var(--cato-ink);
  border-radius: 0;
}
.cato-btn--text:hover {
  color: var(--cato-brand);
  border-bottom-color: var(--cato-brand);
}


/* ------------------------------------------------------------------ */
/* 5. HERO - full-bleed showroom + centered overlay                   */
/* ------------------------------------------------------------------ */
.cato-hero {
  position: relative;
  width: 100%;
  /* theme.css has a bare `section { padding-block: var(--sp-12) }`. Every other
     CATO band sets its own padding and so overrides it silently; the hero never
     did, so it carried 48px of PAGE background above and below a full-bleed
     slide stack - a cream stripe under the header and a second one above the
     stats bar, with the slideshow dots stranded in it. The hero is full-bleed by
     definition and its own __copy carries the inner spacing. */
  padding-block: 0;
  /* Hero + stats band together fill one viewport. Stats band is
     ~200px on desktop, ~320px on mobile (stats grid goes 2-col). */
  min-height: clamp(420px, calc(100vh - 200px), 880px);
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  isolation: isolate;
}
@media (max-width: 768px) {
  .cato-hero { min-height: clamp(420px, calc(100vh - 320px), 720px); }
}
.cato-hero__bg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center 55%;
  z-index: 0;
  display: block;
}
.cato-hero__veil {
  position: absolute;
  inset: 0;
  z-index: 1;
  background:
    linear-gradient(180deg, rgba(0,0,0,0.55) 0%, rgba(0,0,0,0.50) 35%, rgba(0,0,0,0.80) 100%),
    radial-gradient(ellipse 70% 55% at center 52%, rgba(0,0,0,0.45) 0%, rgba(0,0,0,0.10) 80%);
  pointer-events: none;
}
.cato-hero__copy {
  position: relative;
  z-index: 2;
  text-align: center;
  padding: 96px 32px;
}
@media (max-width: 640px) {
  .cato-hero__copy { padding: 80px 20px; }
}
.cato-hero--showroom .cato-display {
  max-width: 18ch;
  margin-left: auto;
  margin-right: auto;
  text-shadow:
    0 2px 4px rgba(0,0,0,0.85),
    0 6px 28px rgba(0,0,0,0.75);
}
.cato-hero--showroom .cato-lead {
  max-width: 58ch;
  font-weight: 500;            /* a touch heavier so it holds against the showroom lighting */
  text-shadow:
    0 1px 3px rgba(0,0,0,0.9),
    0 4px 16px rgba(0,0,0,0.6);
}
/* The eyebrow was --cato-ink-2 (#5C5C5C, a LIGHT-mode muted grey) on a
   near-black veil: 3.14:1, under the 4.5:1 small-text bar, which is why it read
   as barely-there grey on the photo. .cato-eyebrow--light already existed for
   exactly this, but it is a modifier the markup has to remember and every
   showroom page forgot it. Scoping it to the dark hero makes it structural
   instead of something a new page can omit. */
.cato-hero--showroom .cato-eyebrow {
  color: rgba(255,255,255,0.85);
  text-shadow: 0 1px 3px rgba(0,0,0,0.7);
}
.cato-hero--showroom .cato-eyebrow::before { background: var(--cato-hover); }
/* NO blue accent on a dark hero - the accent word stays white.

   This used to be `color: var(--cato-brand)`, i.e. #0000FE sitting on a veil of
   rgba(0,0,0,0.5-0.8): measured 2.43:1, which fails WCAG AA even at the 3:1
   large-text bar, and read as a dark smudge in the middle of a white headline.

   Brand blue simply cannot carry text on a near-black backdrop - its luminance
   is 0.07, so 2.4:1 against pure black is its CEILING no matter how the veil is
   tuned. Lightening the veil to rescue it would cost the white headline more
   than it gained.

   The slideshow hero already settled this the same way further down ("slide
   headlines stay fully white - no blue accent on brand words"). This just brings
   the showroom hero in line, so both dark heroes behave alike and no new blue
   enters the palette. The blue accent stays where it works: headings on the
   light bands. */
.cato-hero--showroom .cato-display em {
  color: inherit;
  text-shadow:
    0 2px 4px rgba(0,0,0,0.85),
    0 6px 24px rgba(0,0,0,0.65);
}
.cato-hero__ctas {
  display: flex;
  flex-wrap: wrap;
  gap: 14px;
  margin: 32px 0 0 0;
}
.cato-hero__ctas--center {
  justify-content: center;
}


/* ------------------------------------------------------------------ */
/* 5b. HERO slideshow variant (uk-slideshow)                          */
/* ------------------------------------------------------------------ */
/* Override the base .cato-hero flex-centering so uk-slideshow can
   position its absolute children. Each <li> becomes the flex frame. */
.cato-hero--slideshow { display: block; }

.cato-hero--slideshow .cato-hero__items,
.cato-hero--slideshow .cato-hero__items {
  list-style: none;
  margin: 0;
  padding: 0;
  min-height: clamp(420px, calc(100vh - 200px), 880px);
}
@media (max-width: 768px) {
  .cato-hero--slideshow .cato-hero__items,
  .cato-hero--slideshow .cato-hero__items {
    min-height: clamp(420px, calc(100vh - 320px), 720px);
  }
}
/* Note: do NOT set position:relative or display on .cato-hero__slide
   directly. UIkit applies position: absolute + inset: 0 to slideshow
   items and uses display:none on :not(.is-active) to keep inactive
   slides hidden. Our centering rule matches UIkit's own selector
   pattern (.cato-hero__items > .is-active) so the flex centering
   only applies to the visible / transitioning slide. */
.cato-hero--slideshow .cato-hero__slide {
  overflow: hidden;
  /* THE SAME min-height AS THE <ul>, and it has to be here too.

     Inactive slides are position:absolute inset:0, so they take the ul's size
     for free. The ACTIVE one is position:relative - that is what gives the ul
     its height - so it was only as tall as its own copy: 532px inside a 700px
     ul. .cato-hero__bg is inset:0 within the slide, so the photo stopped at
     532px too and the remaining ~158px of the hero was transparent, showing the
     cream page background as a blank band above the stats bar with the
     slideshow dots stranded in it.

     A short slide (few words, no lead) is the case that exposed it; a long one
     happened to reach the min-height on its own, which is why this looked
     intermittent. */
  min-height: clamp(420px, calc(100vh - 200px), 880px);
}
@media (max-width: 768px) {
  .cato-hero--slideshow .cato-hero__slide {
    min-height: clamp(420px, calc(100vh - 320px), 720px);
  }
}
.cato-hero--slideshow .cato-hero__items > .is-active {
  display: flex;
  align-items: center;
  justify-content: center;
}
.cato-hero--slideshow .cato-hero__bg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  max-width: none;
  object-fit: cover;
  object-position: center 55%;
  z-index: 0;
  display: block;
  /* slight softening so the background recedes behind the headline.
     overscale prevents blur halos at the edges. */
  filter: blur(2px) saturate(1.05);
  transform: scale(1.04);
}
.cato-hero--slideshow .cato-hero__copy {
  position: relative;
  z-index: 2;
  text-align: center;
  padding: 96px 32px 80px;
}
@media (max-width: 640px) {
  .cato-hero--slideshow .cato-hero__copy { padding: 80px 20px 72px; }
}

/* Shared overlay-text legibility shadows so headline / sub / eyebrow
   stay readable across varied slideshow backgrounds. */
.cato-hero--slideshow .cato-display {
  max-width: 20ch;
  margin-left: auto;
  margin-right: auto;
  text-shadow:
    0 2px 4px rgba(0,0,0,0.85),
    0 6px 28px rgba(0,0,0,0.75);
}
.cato-hero--slideshow .cato-lead {
  max-width: 58ch;
  font-weight: 500;
  text-shadow:
    0 1px 3px rgba(0,0,0,0.9),
    0 4px 16px rgba(0,0,0,0.6);
}
.cato-hero--slideshow .cato-eyebrow {
  color: rgba(255,255,255,0.85);
  text-shadow: 0 1px 3px rgba(0,0,0,0.7);
}
.cato-hero--slideshow .cato-eyebrow::before { background: var(--cato-hover); }
/* slide headlines stay fully white - no blue accent on brand words */
.cato-hero--slideshow .cato-display em {
  color: inherit;
  text-shadow:
    0 2px 4px rgba(0,0,0,0.85),
    0 6px 24px rgba(0,0,0,0.65);
}

/* Brand-logo strip per slide (white logos on dark veil). */
.cato-hero__brand {
  display: block;
  margin: 24px auto 28px;
  max-width: 160px;
  max-height: 56px;
  width: auto;
  height: auto;
  filter: drop-shadow(0 2px 6px rgba(0,0,0,0.6));
}
@media (max-width: 640px) {
  .cato-hero__brand { max-width: 130px; max-height: 44px; }
}

/* Slideshow dot navigation. */
.cato-hero__dots {
  position: absolute;
  bottom: 24px;
  left: 0;
  right: 0;
  z-index: 5;
  display: flex;
  justify-content: center;
  gap: 10px;
  margin: 0;
  padding: 0;
  list-style: none;
}
.cato-hero__dots > li > * {
  background: rgba(255,255,255,0.45);
  border-color: rgba(255,255,255,0.45);
  transition: background 0.2s ease, border-color 0.2s ease;
}
.cato-hero__dots > li.is-active > * {
  background: var(--cato-brand);
  border-color: var(--cato-brand);
}
.cato-hero__dots > li > *:hover,
.cato-hero__dots > li > *:focus-visible {
  background: #FFFFFF;
  border-color: #FFFFFF;
}


/* ------------------------------------------------------------------ */
/* 6. STATS BAR                                                       */
/* ------------------------------------------------------------------ */
.cato-stats {
  padding: 56px 0;
  background: var(--cato-ink);
  color: var(--cato-bg);
  --cato-brand: #FFFFFF;
}
.cato-stats__grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 40px;
  align-items: center;
  list-style: none;
  margin: 0;
  padding: 0;
}
@media (max-width: 768px) {
  .cato-stats__grid {
    grid-template-columns: repeat(2, 1fr);
    gap: 32px 24px;
  }
}
.cato-stat {
  display: flex;
  flex-direction: column;
  gap: 6px;
  border-left: 1px solid rgba(255,255,255,0.18);
  padding-left: 24px;
}
.cato-stat:first-child { border-left: 0; padding-left: 0; }
@media (max-width: 768px) {
  .cato-stat { border-left: 0; padding-left: 0; }
}
.cato-stat__num {
  font-family: 'Oswald', sans-serif;
  font-weight: 600;
  font-size: clamp(40px, 5vw, 64px);
  line-height: 1;
  color: var(--cato-bg);
  letter-spacing: -0.01em;
}
.cato-stat__num em {
  font-style: normal;
  color: var(--cato-brand);
}
.cato-stat__lbl {
  font-family: 'Rubik', sans-serif;
  font-size: 11px;
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: 0.18em;
  color: rgba(255,255,255,0.65);
}


/* ------------------------------------------------------------------ */
/* 7. SERVICES - frosted glass cards                                  */
/* ------------------------------------------------------------------ */
.cato-services__grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 28px;
  margin: 0 0 56px 0;
}
@media (max-width: 1024px) {
  .cato-services__grid { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 560px) {
  .cato-services__grid { grid-template-columns: 1fr; }
}

.cato-frost {
  position: relative;
  display: block;
  overflow: hidden;
  border-radius: var(--cato-radius-lg);
  /* 1/1, was 4/5. The card ratio IS the crop: a 4:5 window onto the 4:3 photos
     these cards use could only ever show 60% of the frame's width, so every card
     read as a close-up no matter which photo went in. Square shows 75%. There is
     no way to widen the view inside a fixed 4:5 window - the ratio had to move. */
  aspect-ratio: 1 / 1;
  background: #1a1a1a;
  box-shadow: var(--cato-shadow);
  isolation: isolate;
}
.cato-frost__img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  max-width: none;             /* override YT/UIkit default img { max-width: 100% } */
  object-fit: cover;
  /* 1.03, was 1.08. The overscale exists so blur(3px) cannot sample past the edge
     and leave a soft halo; 3px of blur needs about 1% of cover, so 1.08 was
     spending 8% of the frame to buy 1%. That 5% comes back as visible photo. */
  transform: scale(1.03);
  transform-origin: center;
  filter: blur(3px) saturate(1.08);
  transition: filter 0.35s ease, transform 0.35s ease;
  z-index: 0;
}
.cato-frost::after {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, rgba(0,0,0,0.05) 40%, rgba(0,0,0,0.40) 100%);
  z-index: 1;
  pointer-events: none;
}
.cato-frost__panel {
  position: absolute;
  left: 16px;
  right: 16px;
  bottom: 16px;
  padding: 18px 20px 16px;
  background: rgba(255,255,255,0.18);
  -webkit-backdrop-filter: blur(18px) saturate(1.4);
          backdrop-filter: blur(18px) saturate(1.4);
  border: 1px solid rgba(255,255,255,0.32);
  border-radius: var(--cato-radius);
  z-index: 2;
}
.cato-frost__num {
  display: block;
  margin: 0 0 6px 0;
  font-family: 'Rubik', sans-serif;
  font-size: 10px;
  font-weight: 500;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: rgba(255,255,255,0.85);
  text-shadow: 0 1px 3px rgba(0,0,0,0.5);
}
.cato-frost__title {
  margin: 0 0 4px 0;
  font-family: 'Oswald', sans-serif;
  font-weight: 600;
  font-size: 22px;
  line-height: 1.1;
  color: #FFFFFF;
  text-shadow: 0 2px 8px rgba(0,0,0,0.55);
}
.cato-frost__desc {
  margin: 0;
  font-family: 'Roboto', sans-serif;
  font-size: 13.5px;
  line-height: 1.4;
  color: #FFFFFF;
  text-shadow: 0 1px 4px rgba(0,0,0,0.55);
}
.cato-frost:hover .cato-frost__img,
.cato-frost:focus-within .cato-frost__img {
  filter: blur(1.5px) saturate(1.15);
  transform: scale(1.07);
}
@supports not ((-webkit-backdrop-filter: blur(1px)) or (backdrop-filter: blur(1px))) {
  .cato-frost__panel {
    background: rgba(20,20,20,0.78);
    border-color: rgba(255,255,255,0.12);
  }
}
@media (max-width: 560px) {
  .cato-frost__panel { left: 12px; right: 12px; bottom: 12px; padding: 14px 16px 12px; }
  .cato-frost__title { font-size: 19px; }
  .cato-frost__desc  { font-size: 13px; }
}

.cato-services__cta {
  display: flex;
  justify-content: center;
  gap: 14px;
  flex-wrap: wrap;
}


/* ------------------------------------------------------------------ */
/* 7a. SHOWROOM band - "Since 2019" + service areas                   */
/* Photo bleeds ~6vw past the left edge of the viewport. Copy column  */
/* sits on the right inside the standard container. Mobile collapses  */
/* to stacked photo-above-copy.                                       */
/* ------------------------------------------------------------------ */
.cato-showroom {
  position: relative;
  overflow: hidden;
  background: var(--cato-surface);
  border-top: 1px solid var(--cato-rule);
  border-bottom: 1px solid var(--cato-rule);
  padding: 120px 0;
}
.cato-showroom__media-wrap {
  position: absolute;
  left: -6vw;
  top: 50%;
  transform: translateY(-50%);
  width: 56vw;
  max-width: 820px;
  height: clamp(420px, 60vh, 640px);
  border-radius: 0 var(--cato-radius-lg) var(--cato-radius-lg) 0;
  overflow: hidden;
  box-shadow: var(--cato-shadow-lg);
  z-index: 0;
}
.cato-showroom__media-img {
  width: 100%;
  height: 100%;
  max-width: none;
  object-fit: cover;
  display: block;
}
.cato-showroom__inner {
  position: relative;
  z-index: 1;
  display: grid;
  grid-template-columns: 1fr 1fr;
  align-items: center;
  min-height: clamp(420px, 60vh, 640px);
  gap: 64px;
}
.cato-showroom__copy {
  grid-column: 2;
  padding-right: 16px;
}
.cato-showroom__copy .cato-display { margin-bottom: 16px; }
.cato-showroom__areas-label {
  margin: 20px 0 12px;
  font-family: 'Rubik', sans-serif;
  font-size: 12px;
  font-weight: 500;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--cato-ink-2);
}
.cato-showroom__areas {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 8px 24px;
  list-style: none;
  margin: 0 0 32px 0;
  padding: 0;
}
.cato-showroom__areas li {
  position: relative;
  padding-left: 22px;
  font-family: 'Roboto', sans-serif;
  font-size: 15px;
  font-weight: 500;
  letter-spacing: 0.01em;
  color: var(--cato-ink);
}
.cato-showroom__areas li::before {
  content: '';
  position: absolute;
  left: 0;
  top: 50%;
  width: 14px;
  height: 1px;
  background: var(--cato-brand);
  transform: translateY(-50%);
}
.cato-showroom__ctas {
  display: flex;
  gap: 14px;
  flex-wrap: wrap;
}
@media (max-width: 900px) {
  .cato-showroom { padding: 56px 0; }
  .cato-showroom__media-wrap {
    position: relative;
    left: 0;
    top: auto;
    transform: none;
    width: calc(100% - 40px);
    max-width: none;
    height: auto;
    aspect-ratio: 4 / 3;
    margin: 0 20px 32px;
    border-radius: var(--cato-radius-lg);
  }
  .cato-showroom__inner {
    grid-template-columns: 1fr;
    min-height: 0;
    gap: 0;
  }
  .cato-showroom__copy {
    grid-column: 1;
    padding: 0 20px;
  }
}
@media (max-width: 480px) {
  .cato-showroom__areas { grid-template-columns: 1fr; }
}


/* ------------------------------------------------------------------ */
/* 7b. OUR WORK - 6-tile gallery preview                              */
/* ------------------------------------------------------------------ */
.cato-work__grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-auto-rows: 1fr;
  gap: 20px;
  margin: 0 0 40px 0;
}
@media (max-width: 900px) { .cato-work__grid { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 540px) { .cato-work__grid { grid-template-columns: 1fr; } }

.cato-work__tile {
  position: relative;
  display: block;
  overflow: hidden;
  border-radius: var(--cato-radius-lg);
  aspect-ratio: 4 / 3;
  background: #1a1a1a;
  box-shadow: var(--cato-shadow-sm);
  transition: box-shadow 0.3s ease, transform 0.3s ease;
}
.cato-work__tile img {
  width: 100%;
  height: 100%;
  max-width: none;             /* override YT/UIkit max-width: 100% */
  object-fit: cover;
  display: block;
  transform: scale(1.02);
  transition: transform 0.5s ease, filter 0.4s ease;
  filter: saturate(1.02);
}
.cato-work__tile:hover img,
.cato-work__tile:focus-visible img {
  transform: scale(1.08);
  filter: saturate(1.12);
}
.cato-work__tile:hover,
.cato-work__tile:focus-visible {
  box-shadow: var(--cato-shadow);
  transform: translateY(-2px);
}

.cato-work__cta {
  display: flex;
  justify-content: center;
}


/* ------------------------------------------------------------------ */
/* 8. ROYAL - exclusive dealer callout                                */
/* ------------------------------------------------------------------ */
.cato-royal {
  background: var(--cato-surface);
  border-top: 1px solid var(--cato-rule);
  border-bottom: 1px solid var(--cato-rule);
}
.cato-royal__head {
  max-width: 760px;
  margin: 0 auto 56px auto;
  text-align: center;
}
.cato-royal__head .cato-eyebrow,
.cato-royal__head .cato-display { justify-content: center; text-align: center; }
.cato-royal__head .cato-eyebrow { display: inline-flex; }
.cato-royal__head .cato-lead    { margin-left: auto; margin-right: auto; text-align: center; }
.cato-royal__head .cato-btn--text { margin-top: 8px; }

.cato-royal__grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 24px;
}
@media (max-width: 900px)  { .cato-royal__grid { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 560px)  { .cato-royal__grid { grid-template-columns: 1fr; } }

.cato-royal__card {
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: 16px;
}
.cato-royal__card img {
  width: 100%;
  height: auto;
  aspect-ratio: 4 / 3;
  object-fit: cover;
  display: block;
  border-radius: var(--cato-radius-lg);
  box-shadow: var(--cato-shadow-sm);
  transition: transform 0.5s ease, box-shadow 0.3s ease;
}
.cato-royal__card:hover img,
.cato-royal__card:focus-within img {
  transform: translateY(-3px);
  box-shadow: var(--cato-shadow);
}
.cato-royal__card figcaption {
  font-family: 'Oswald', sans-serif;
  font-size: 18px;
  font-weight: 500;
  letter-spacing: 0.02em;
  color: var(--cato-ink);
  text-align: center;
}


/* ------------------------------------------------------------------ */
/* 7c. CATEGORY CHIPS - the homepage signpost to /inventory           */
/* ------------------------------------------------------------------ */
/* Replaces the old full category card grid. No images by design: the
   categories mostly have none, so cards rendered as rows of identical
   grey placeholder icons. */
.cato-cathips {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: .625rem;
  margin: 2.5rem 0 0;
  padding: 0;
  list-style: none;
}
.cato-cathip {
  display: inline-flex;
  align-items: center;
  gap: .5rem;
  padding: .6rem 1rem;
  border: 1px solid var(--color-border);
  border-radius: 999px;
  background: var(--color-bg-alt, #FFFFFF);
  color: var(--cato-ink, inherit);
  font-weight: 600;
  font-size: .9375rem;
  line-height: 1.2;
  text-decoration: none;
  transition: border-color .2s ease, background .2s ease, color .2s ease;
}
/* The chips are a plain list since 2026-09-24, not links, so no hover state:
   a colour change on hover would promise a click that does nothing. */
/* Count pill. Inherits currentColor so it flips with the chip on hover
   instead of needing a second hover rule. */
.cato-cathip__n {
  font-size: .75rem;
  font-weight: 700;
  opacity: .6;
  font-variant-numeric: tabular-nums;
}
.cato-cathips__cta { margin-top: 2rem; text-align: center; }

/* ------------------------------------------------------------------ */
/* 8b. FINANCING - Synchrony banner                                   */
/* ------------------------------------------------------------------ */
.cato-finance {
  padding: 48px 0;
  background: var(--cato-bg);
}
.cato-finance__banner {
  display: block;
  width: 100%;
  border-radius: var(--cato-radius-lg);
  overflow: hidden;
  box-shadow: var(--cato-shadow-sm);
  transition: box-shadow 0.3s ease, transform 0.3s ease;
}
.cato-finance__banner img {
  display: block;
  width: 100%;
  height: auto;
  max-width: none;
  object-fit: cover;
}
.cato-finance__banner:hover,
.cato-finance__banner:focus-visible {
  box-shadow: var(--cato-shadow);
  transform: translateY(-2px);
}


/* ------------------------------------------------------------------ */
/* 9. BRANDS - 22-logo static grid                                    */
/* ------------------------------------------------------------------ */
.cato-brands {
  background: var(--cato-bg);
  padding: 96px 0;
  border-top: 1px solid var(--cato-rule);
}
.cato-brands .cato-section__head { margin-bottom: 48px; }
.cato-brands__grid {
  display: grid;
  grid-template-columns: repeat(6, 1fr);
  gap: 12px 24px;
  list-style: none;
  margin: 0;
  padding: 0;
}
@media (max-width: 1024px) { .cato-brands__grid { grid-template-columns: repeat(4, 1fr); } }
@media (max-width: 540px)  { .cato-brands__grid { grid-template-columns: repeat(2, 1fr); } }
.cato-brands__item {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 96px;
  padding: 8px;
}
.cato-brands__item a {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 100%;
}
.cato-brands__item img {
  max-width: 100%;
  max-height: 60px;
  width: auto; height: auto;
  object-fit: contain;
  transition: transform 0.25s ease;
}
.cato-brands__item:hover img,
.cato-brands__item:focus-within img {
  transform: scale(1.04);
}


/* ------------------------------------------------------------------ */
/* 10. REVIEWS                                                        */
/* ------------------------------------------------------------------ */
.cato-reviews {
  background: var(--cato-bg);
  border-top: 1px solid var(--cato-rule);
}
.cato-reviews .reviewmgr-stream { margin-top: 40px; }


/* ------------------------------------------------------------------ */
/* 11. NTEA - diamond plate band                                      */
/* ------------------------------------------------------------------ */
.cato-ntea {
  position: relative;
  padding: 96px 0;
  overflow: hidden;
  isolation: isolate;
  color: #FFFFFF;
  --cato-brand: #FFFFFF;
}
.cato-ntea__bg {
  position: absolute;
  inset: 0;
  background-size: cover;
  background-position: center;
  z-index: 0;
}
.cato-ntea__veil {
  position: absolute;
  inset: 0;
  /* Keep the text zone (left ~65%) dark so the blue "Work Truck Association"
     headline has real contrast. Blue tint only kicks in on the right edge as
     decoration on top of the diamond plate. */
  background: linear-gradient(120deg, rgba(8,8,8,0.95) 0%, rgba(8,8,8,0.88) 65%, rgba(0,0,254,0.45) 100%);
  z-index: 1;
}
.cato-ntea__inner {
  position: relative;
  z-index: 2;
  display: grid;
  grid-template-columns: minmax(220px, 320px) 1fr;
  gap: 56px;
  align-items: center;
}
@media (max-width: 768px) {
  .cato-ntea__inner { grid-template-columns: 1fr; gap: 28px; text-align: left; }
}
.cato-ntea__logo {
  width: 100%;
  max-width: 280px;
  height: auto;
  filter: drop-shadow(0 6px 18px rgba(0,0,0,0.45));
  background: rgba(255,255,255,0.94);
  padding: 18px 22px;
  border-radius: var(--cato-radius);
}
.cato-ntea__copy .cato-eyebrow { color: rgba(255,255,255,0.78); }
.cato-ntea__copy .cato-eyebrow::before { background: var(--cato-brand); }
.cato-ntea__copy .cato-display { color: #FFFFFF; }
.cato-ntea__copy .cato-display em { color: var(--cato-brand); }
.cato-ntea__copy .cato-lead { color: rgba(255,255,255,0.88); max-width: 64ch; }


/* ------------------------------------------------------------------ */
/* 12. CONTACT - dark band + map                                      */
/* ------------------------------------------------------------------ */
.cato-contact {
  background: var(--cato-ink);
  color: var(--cato-bg);
  padding: 96px 0;
}
.cato-contact__inner {
  display: grid;
  grid-template-columns: 5fr 7fr;
  gap: 64px;
  align-items: stretch;
}
@media (max-width: 900px) {
  .cato-contact__inner { grid-template-columns: 1fr; gap: 40px; }
}
.cato-contact .cato-eyebrow { color: rgba(255,255,255,0.65); }
.cato-contact .cato-eyebrow::before { background: #FFFFFF; }
.cato-contact .cato-display { color: var(--cato-bg); }
.cato-contact .cato-display em { color: #FFFFFF; }
.cato-contact .cato-lead { color: rgba(255,255,255,0.88); }

.cato-contact__list {
  list-style: none;
  margin: 24px 0 32px 0;
  padding: 0;
}
.cato-contact__list li {
  padding: 14px 0;
  border-bottom: 1px solid rgba(255,255,255,0.12);
  font-family: 'Rubik', sans-serif;
  font-size: 14px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: rgba(255,255,255,0.92);
}
.cato-contact__list li a { color: inherit; display: inline-flex; align-items: center; gap: 10px; }
.cato-contact__list li a:hover { color: var(--cato-hover); }

.cato-contact__ctas {
  display: flex;
  gap: 14px;
  flex-wrap: wrap;
}
/* contact section is dark - secondary button keeps the global white-bg/blue-text style
   so it stands out against the black band. no per-section override. */

.cato-contact__map {
  position: relative;
  aspect-ratio: 5 / 4;
  overflow: hidden;
  border-radius: var(--cato-radius-lg);
  box-shadow: var(--cato-shadow-lg);
  background: #2a2a2a;
  min-height: 320px;

  /* PORT FIX 2026-08-18 — this made the whole page scroll sideways by 229px.
     The parent is a grid with align-items: stretch, so this box was stretched
     to the row height set by the copy column. With aspect-ratio: 5/4 and no
     definite width, the ratio then resolved the OTHER way and computed the
     WIDTH from that stretched height: 1053px in a track that was ~850px.

     align-self: start stops the stretch, so width comes from the track and the
     ratio derives the height, which is the direction it was written for.
     min-width: 0 is the companion fix — a grid item's default min-width is
     auto, which refuses to shrink below its content and would let a wide
     iframe push the track out again.

     Not a bug in the approved sheet. In YOOtheme this block sat in a builder
     row whose column already had a definite width, so the ratio never had a
     chance to resolve backwards. It only appears once the design is lifted
     into a plain CSS grid, which is exactly what the port did. */
  align-self: start;
  width: 100%;
  min-width: 0;
}
.cato-contact__map iframe {
  position: absolute;
  inset: 0;
  width: 100%; height: 100%;
  border: 0;
}


/* ------------------------------------------------------------------ */
/* 13. Reveal-on-scroll                                               */
/* ------------------------------------------------------------------ */
.cato-reveal {
  opacity: 0;
  transform: translateY(20px);
  transition: opacity 0.7s ease, transform 0.7s ease;
}
.cato-reveal.cato-in {
  opacity: 1;
  transform: translateY(0);
}


/* =====================================================================
   PHASE 2 ADDITIONS - Service-area pages, Contact, What We Do
   Appended to the same single stylesheet. Page-content classes are
   scoped under .cato-page; classes that style elements OUTSIDE the
   .cato-page wrapper (the live WPForms form, YT Dynamic Content post
   grids) are intentionally NOT scoped and use hardcoded brand values
   (the --brand token does not resolve outside .cato-page).
   ===================================================================== */


/* ------------------------------------------------------------------ */
/* 14. WHY {CITY} CHOOSES CATO - 3 callouts (service-area pages)       */
/* ------------------------------------------------------------------ */
.cato-why {
  background: var(--cato-surface);
  border-top: 1px solid var(--cato-rule);
  border-bottom: 1px solid var(--cato-rule);
  padding: 96px 0;
}
@media (max-width: 768px) { .cato-why { padding: 56px 0; } }
.cato-why .cato-section__head { margin-bottom: 48px; }
.cato-why__grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 32px;
  list-style: none;
  margin: 0;
  padding: 0;
}
@media (max-width: 768px) { .cato-why__grid { grid-template-columns: 1fr; gap: 24px; } }
.cato-why__item {
  background: var(--cato-bg);
  border: 1px solid var(--cato-rule);
  border-radius: var(--cato-radius-lg);
  padding: 36px 28px;
  text-align: center;
  box-shadow: var(--cato-shadow-sm);
  transition: transform 0.3s ease, box-shadow 0.3s ease;
}
.cato-why__item:hover { transform: translateY(-3px); box-shadow: var(--cato-shadow); }
.cato-why__icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 64px;
  height: 64px;
  margin: 0 0 18px 0;
  color: var(--cato-brand);
  background: rgba(0,0,254,0.06);
  border-radius: 50%;
}
.cato-why__title {
  margin: 0 0 10px 0;
  font-family: 'Oswald', sans-serif;
  font-weight: 600;
  font-size: 22px;
  line-height: 1.1;
  color: var(--cato-ink);
}
.cato-why__text {
  margin: 0;
  font-family: 'Roboto', sans-serif;
  font-size: 15px;
  line-height: 1.55;
  color: var(--cato-ink-2);
}


/* ------------------------------------------------------------------ */
/* 15. CLOSING CTA band (service-area + What We Do)                   */
/* ------------------------------------------------------------------ */
.cato-cta {
  background: var(--cato-surface);
  border-top: 1px solid var(--cato-rule);
  text-align: center;
}
.cato-cta .cato-section__head { margin-bottom: 32px; }


/* ------------------------------------------------------------------ */
/* 16. CONTACT PAGE - form + info, team, mission, map                 */
/* ------------------------------------------------------------------ */
.cato-contactpg__grid {
  display: grid;
  grid-template-columns: 5fr 7fr;
  gap: 56px;
  align-items: start;
}
@media (max-width: 900px) { .cato-contactpg__grid { grid-template-columns: 1fr; gap: 40px; } }

.cato-info .cato-display { margin-bottom: 24px; }
.cato-info__list {
  list-style: none;
  margin: 0 0 32px 0;
  padding: 0;
}
.cato-info__list li {
  display: flex;
  align-items: flex-start;
  gap: 14px;
  padding: 16px 0;
  border-bottom: 1px solid var(--cato-rule);
  font-family: 'Roboto', sans-serif;
  font-size: 16px;
  line-height: 1.5;
  color: var(--cato-ink);
}
.cato-info__list li a { color: var(--cato-ink); }
.cato-info__list li a:hover { color: var(--cato-brand); }
.cato-info__icon { color: var(--cato-brand); flex: 0 0 auto; margin-top: 2px; }
/* Label left, action right. Both children are inline-flex, so they already sat
   on one line - but hard against each other, leaving ~150px of dead box to the
   RIGHT of the button and making the row look like it had come untucked.
   space-between spends that gap between them instead, which is the ordinary
   shape for a label-and-action strip. Wraps to a stack on a narrow column. */
.cato-quote {
  margin-top: 8px;
  padding: 24px;
  background: var(--cato-bg);
  border: 1px solid var(--cato-rule);
  border-radius: var(--cato-radius-lg);
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
}
/* Was stacking space under an eyebrow that is now a flex row item. */
.cato-quote .cato-eyebrow { margin-bottom: 0; }
.cato-quote .cato-eyebrow::before { display: none; }

.cato-form-slot {
  background: var(--cato-surface);
  border: 1px solid var(--cato-rule);
  border-radius: var(--cato-radius-lg);
  padding: 40px;
  box-shadow: var(--cato-shadow-sm);
}
.cato-form-slot .cato-display { margin-bottom: 16px; }
.cato-form-slot__note {
  font-family: 'Roboto', sans-serif;
  font-size: 14px;
  color: var(--cato-ink-2);
  font-style: italic;
}

/* Team directory */
.cato-team {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 24px;
  list-style: none;
  margin: 0;
  padding: 0;
}
@media (max-width: 900px) { .cato-team { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 560px) { .cato-team { grid-template-columns: 1fr; } }
.cato-team__card {
  background: var(--cato-surface);
  border: 1px solid var(--cato-rule);
  border-radius: var(--cato-radius-lg);
  padding: 28px 24px;
  box-shadow: var(--cato-shadow-sm);
  transition: transform 0.3s ease, box-shadow 0.3s ease;
  overflow: hidden;
}
.cato-team__card:hover { transform: translateY(-3px); box-shadow: var(--cato-shadow); }
.cato-team__name {
  margin: 0 0 4px 0;
  font-family: 'Oswald', sans-serif;
  font-weight: 600;
  font-size: 22px;
  color: var(--cato-ink);
}
.cato-team__role {
  margin: 0 0 16px 0;
  font-family: 'Rubik', sans-serif;
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--cato-brand);
}
.cato-team__email {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-family: 'Roboto', sans-serif;
  font-size: 13.5px;
  color: var(--cato-ink-2);
  word-break: break-all;
}
.cato-team__email:hover { color: var(--cato-brand); }
.cato-team__email .cato-icon { flex: 0 0 auto; }
.cato-team__photo {
  display: block;
  width: calc(100% + 48px);
  margin: -28px -24px 24px -24px;
  aspect-ratio: 3 / 4;
  object-fit: cover;
  object-position: top center;
  border-radius: var(--cato-radius-lg) var(--cato-radius-lg) 0 0;
}

/* Mission + Guarantee - dark band */
.cato-mission {
  background: var(--cato-ink);
  color: var(--cato-bg);
  padding: 96px 0;
  --cato-brand: #FFFFFF;
}
@media (max-width: 768px) { .cato-mission { padding: 56px 0; } }
.cato-mission .cato-container { }
.cato-mission__lead { max-width: 820px; margin: 0 auto 56px auto; text-align: center; }
.cato-mission__lead .cato-eyebrow { justify-content: center; color: rgba(255,255,255,0.78); }
.cato-mission__lead .cato-eyebrow::before { background: var(--cato-brand); }
.cato-mission__lead .cato-display { color: #FFFFFF; }
.cato-mission__lead .cato-display em { color: var(--cato-brand); }
.cato-mission__lead .cato-lead { color: rgba(255,255,255,0.88); margin-left: auto; margin-right: auto; text-align: center; max-width: 70ch; }
.cato-mission__grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 32px;
  list-style: none;
  margin: 0;
  padding: 0;
}
@media (max-width: 768px) { .cato-mission__grid { grid-template-columns: 1fr; gap: 24px; } }
.cato-mission__item {
  border-top: 2px solid var(--cato-brand);
  padding: 24px 4px 0;
}
.cato-mission__icon { display: block; color: var(--cato-brand); margin: 0 0 14px 0; }
.cato-mission__title {
  margin: 0 0 10px 0;
  font-family: 'Oswald', sans-serif;
  font-weight: 600;
  font-size: 20px;
  color: #FFFFFF;
}
.cato-mission__text {
  margin: 0;
  font-family: 'Roboto', sans-serif;
  font-size: 14.5px;
  line-height: 1.55;
  color: rgba(255,255,255,0.82);
}

/* Map section */
.cato-map-sec { padding: 0; }
/* Same aspect-ratio-in-a-grid trap as .cato-contact__map above. */
.cato-map-sec__frame {
  min-width: 0;
  position: relative;
  width: 100%;
  height: clamp(360px, 50vh, 520px);
  overflow: hidden;
  background: #2a2a2a;
}
.cato-map-sec__frame iframe {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  border: 0;
}
/* A keyboard user tabbing into a map saw no focus ring: both frames clip with
   overflow:hidden, so an outside outline is cut off. Inset it instead. */
.cato-contact__map iframe:focus-visible,
.cato-map-sec__frame iframe:focus-visible {
  outline: 3px solid #0000FE;
  outline-offset: -3px;
}


/* ------------------------------------------------------------------ */
/* 17. WHAT WE DO - dynamic post grid heads                           */
/* ------------------------------------------------------------------ */
.cato-posts-head .cato-section__head { margin-bottom: 0; }

/* ------------------------------------------------------------------ */
/* 20. SERVICE AREAS hub - city cards                                 */
/* ------------------------------------------------------------------ */
.cato-areas__grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 24px;
  list-style: none;
  margin: 0;
  padding: 0;
}
@media (max-width: 900px) { .cato-areas__grid { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 560px) { .cato-areas__grid { grid-template-columns: 1fr; } }
.cato-areas__grid > li { display: flex; }

.cato-area-card {
  position: relative;
  display: flex;
  flex-direction: column;
  width: 100%;
  padding: 32px 28px;
  background: var(--cato-surface);
  border: 1px solid var(--cato-rule);
  border-radius: var(--cato-radius-lg);
  box-shadow: var(--cato-shadow-sm);
  transition: transform 0.3s ease, box-shadow 0.3s ease, border-color 0.3s ease;
}
.cato-area-card:hover,
.cato-area-card:focus-visible {
  transform: translateY(-4px);
  box-shadow: var(--cato-shadow);
  border-color: var(--cato-brand);
}
.cato-area-card--home {
  border-color: var(--cato-brand);
  background: linear-gradient(180deg, rgba(0,0,254,0.04) 0%, var(--cato-surface) 60%);
}
.cato-area-card__tag {
  position: absolute;
  top: 18px;
  right: 18px;
  font-family: 'Rubik', sans-serif;
  font-size: 10px;
  font-weight: 500;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: #FFFFFF;
  background: var(--cato-brand);
  padding: 5px 10px;
  border-radius: 999px;
}
.cato-area-card__icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 56px;
  height: 56px;
  margin: 0 0 18px 0;
  color: var(--cato-brand);
  background: rgba(0,0,254,0.06);
  border-radius: 50%;
}
.cato-area-card__city {
  margin: 0 0 8px 0;
  font-family: 'Oswald', sans-serif;
  font-weight: 600;
  font-size: 26px;
  line-height: 1.05;
  color: var(--cato-ink);
}
.cato-area-card__hook {
  margin: 0 0 24px 0;
  font-family: 'Roboto', sans-serif;
  font-size: 15px;
  line-height: 1.5;
  color: var(--cato-ink-2);
  flex: 1 1 auto;
}
.cato-area-card__link {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-family: 'Oswald', sans-serif;
  font-size: 14px;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--cato-brand);
}
.cato-area-card:hover .cato-area-card__link .cato-icon,
.cato-area-card:focus-visible .cato-area-card__link .cato-icon {
  transform: translateX(4px);
  transition: transform 0.2s ease;
}


/* ============================================================================
   PORT ADDENDUM - what UIkit used to supply
   ----------------------------------------------------------------------------
   The approved sheet was written against uk-slideshow and uk-icon, so it styled
   only the parts UIkit did NOT own. Those two blocks are what UIkit owned. They
   live at the bottom, after the ported sheet, so the port above stays a clean
   diff against the file the client approved.
   ============================================================================ */

/* --- Slideshow scaffolding -------------------------------------------------
   Section 5b's comment says "do NOT set position or display on
   .cato-hero__slide directly" because UIkit did it. UIkit is gone, so we do it
   here instead - same contract, same selectors, so 5b still lands on its feet.

   Fade rather than slide: the approved config asked for animation: fade, and a
   cross-fade between two full-bleed photos does not need transforms. */
.cato-hero--slideshow .cato-hero__items { position: relative; }
.cato-hero--slideshow .cato-hero__slide {
  position: absolute;
  inset: 0;
  opacity: 0;
  visibility: hidden;
  transition: opacity 700ms var(--ease, ease), visibility 0s linear 700ms;
}
.cato-hero--slideshow .cato-hero__items > .is-active {
  position: relative;   /* the active slide is what gives the <ul> its height */
  opacity: 1;
  visibility: visible;
  transition: opacity 700ms var(--ease, ease), visibility 0s;
}

/* NO-JS FALLBACK. Without this the hero is a stack of invisible slides and the
   page opens on nothing at all - which is worse than no slideshow. The first
   slide carries fetchpriority=high and real <h1> copy, so showing it alone is a
   complete hero. .cato-hero--ready is set by JS on first run. */
.cato-hero--slideshow:not(.cato-hero--ready) .cato-hero__slide:first-child {
  position: relative;
  opacity: 1;
  visibility: visible;
}
.cato-hero--slideshow:not(.cato-hero--ready) .cato-hero__dots { display: none; }

/* Reduced motion: no auto-advance (enforced in JS too), no cross-fade. */
@media (prefers-reduced-motion: reduce) {
  .cato-hero--slideshow .cato-hero__slide,
  .cato-hero--slideshow .cato-hero__items > .is-active { transition: none; }
}

/* --- Icons -----------------------------------------------------------------
   uk-icon was an icon FONT plus a JS pass that swapped <span uk-icon> for SVG.
   Both are gone. .cato-icon is a plain inline <svg> sized to the type it sits
   next to, which also means it inherits currentColor on the inverse bands
   without a second rule. aria-hidden on every one: the label is always the
   adjacent text, so announcing the glyph would just be a duplicate. */
.cato-icon {
  width: 1.05em;
  height: 1.05em;
  flex: 0 0 auto;
  vertical-align: -0.15em;
  margin-right: .5em;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.75;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.cato-icon:last-child { margin-right: 0; }


/* ============================================================================
   ADMIN — gallery grid
   ----------------------------------------------------------------------------
   admin/gallery.php only. It is here rather than in shop.css because the admin
   loads cato.css anyway and this is CATO-specific furniture, not chassis.

   Every tile is an independent little form. The layout has to survive a title
   of two words and a title of twenty, so the tile is a column with the image at
   a fixed ratio and the fields flowing under it.
   ============================================================================ */
.admin-gallery-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: 1rem;
}
.admin-gallery-tile {
  position: relative;
  display: flex;
  flex-direction: column;
  background: var(--color-bg-alt);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  overflow: hidden;
}
.admin-gallery-tile > img {
  width: 100%;
  aspect-ratio: 4 / 3;
  object-fit: cover;
  display: block;
  background: var(--color-bg-sunk);
}
.admin-gallery-tile__body {
  display: flex;
  flex-direction: column;
  gap: .4rem;
  padding: .6rem;
}
.admin-gallery-tile__body input[type="text"],
.admin-gallery-tile__body input[type="number"],
.admin-gallery-tile__body select {
  width: 100%;
  font-size: .875rem;
  padding: .35rem .5rem;
}
.admin-gallery-tile__row {
  display: flex;
  align-items: center;
  gap: .4rem;
  flex-wrap: wrap;
  font-size: .8125rem;
}
.admin-gallery-tile__row label { display: flex; align-items: center; gap: .25rem; white-space: nowrap; }

/* The select-for-bulk checkbox. Sits ON the photo, with its own opaque chip so
   it stays visible over a light sky or a white truck. */
.admin-gallery-tile__pick {
  position: absolute;
  top: .4rem; left: .4rem;
  z-index: 2;
  background: var(--color-bg-alt);
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-sm);
  padding: .25rem .4rem;
  line-height: 1;
  cursor: pointer;
}


/* ============================================================================
   GALLERY — filters, grid, lightbox
   ----------------------------------------------------------------------------
   The approved design never had a gallery page (its six tiles linked to one
   that did not exist), so this is new work built in the approved vocabulary:
   the same frosted-card feel as the service grid, the same blue-and-black rule,
   the same eyebrow/display heading pair.
   ============================================================================ */

/* --- Filter chips ---------------------------------------------------------- */
.cato-gallery__filters {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  justify-content: center;
}
.cato-chip {
  display: inline-flex;
  align-items: center;
  gap: .45em;
  padding: 9px 16px;
  border: 1px solid var(--cato-rule);
  border-radius: 999px;
  background: var(--cato-surface);
  color: var(--cato-ink);
  font-family: var(--font-display);
  font-size: .9375rem;
  letter-spacing: .01em;
  text-decoration: none;
  transition: background var(--dur-fast) var(--ease), border-color var(--dur-fast) var(--ease);
}
.cato-chip:hover,
.cato-chip:focus-visible {
  border-color: var(--cato-brand);
  color: var(--cato-brand);
}
.cato-chip.is-active {
  background: var(--cato-brand);
  border-color: var(--cato-brand);
  color: var(--cato-brand-ink);
}
.cato-chip__n {
  font-size: .8125rem;
  opacity: .7;
}
.cato-chip.is-active .cato-chip__n { opacity: .85; }

/* --- Grid ------------------------------------------------------------------ */
.cato-gallery__grid {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
  gap: 20px;
}
@media (max-width: 640px) {
  .cato-gallery__grid { grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 12px; }
}

.cato-gallery__item {
  margin: 0;
  position: relative;
  border-radius: var(--cato-radius-lg);
  overflow: hidden;
  background: var(--cato-surface);
  box-shadow: var(--cato-shadow-sm);
}

/* The zoom button is INSERTED BY JS around the image. Styling it as a bare
   block means the tile looks identical whether or not the script ran. */
.cato-gallery__zoom {
  display: block;
  width: 100%;
  padding: 0;
  border: 0;
  background: none;
  cursor: zoom-in;
}
.cato-gallery__zoom:focus-visible {
  outline: 3px solid var(--cato-brand);
  outline-offset: -3px;
}

.cato-gallery__item img {
  display: block;
  width: 100%;
  aspect-ratio: 4 / 3;
  object-fit: cover;
  transition: transform var(--dur-base) var(--ease);
}
.cato-gallery__item:hover img { transform: scale(1.04); }
@media (prefers-reduced-motion: reduce) {
  .cato-gallery__item img,
  .cato-gallery__item:hover img { transition: none; transform: none; }
}

.cato-gallery__item figcaption {
  padding: 12px 14px 14px;
  font-size: .875rem;
  line-height: 1.4;
  color: var(--cato-ink-2);
}
.cato-gallery__item figcaption strong {
  display: block;
  font-family: var(--font-display);
  font-weight: 600;
  color: var(--cato-ink);
  letter-spacing: .01em;
}

/* --- Lightbox --------------------------------------------------------------
   A <dialog>, so focus trapping and Escape come from the platform. */
.cato-lightbox {
  border: 0;
  padding: 0;
  /* Pinned to the window's edges, not sized in 100vw/100%: on Windows a
     classic scrollbar made the dialog ~17px wider than the visible area and
     cut the close and next buttons in half (2026-10-01). */
  position: fixed;
  inset: 0;
  margin: 0;
  width: auto;
  height: auto;
  max-width: none;
  max-height: none;
  background: transparent;
  overflow: hidden;
}
.cato-lightbox::backdrop { background: rgba(8, 8, 8, .92); }

.cato-lightbox__fig {
  margin: 0;
  position: absolute;
  inset: 56px 64px 64px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 14px;
}
.cato-lightbox__fig img {
  max-width: 100%;
  max-height: calc(100% - 3rem);
  object-fit: contain;
  border-radius: var(--cato-radius);
}
.cato-lightbox__fig figcaption {
  color: #FFFFFF;
  text-align: center;
  font-size: .9375rem;
  max-width: 60ch;
}
.cato-lightbox__fig figcaption strong {
  font-family: var(--font-display);
  display: block;
}

.cato-lightbox__close,
.cato-lightbox__nav {
  position: absolute;
  z-index: 2;
  border: 1px solid rgba(255, 255, 255, .35);
  background: rgba(8, 8, 8, .55);
  color: #FFFFFF;
  border-radius: 999px;
  cursor: pointer;
  line-height: 1;
  transition: background var(--dur-fast) var(--ease);
}
.cato-lightbox__close:hover,
.cato-lightbox__nav:hover { background: var(--cato-brand); border-color: var(--cato-brand); }
.cato-lightbox__close:focus-visible,
.cato-lightbox__nav:focus-visible { outline: 3px solid #FFFFFF; outline-offset: 2px; }

.cato-lightbox__close {
  top: 12px; right: 12px;
  width: 44px; height: 44px;
  font-size: 1.75rem;
}
.cato-lightbox__nav {
  top: 50%;
  transform: translateY(-50%);
  width: 48px; height: 64px;
  font-size: 2rem;
}
.cato-lightbox__nav--prev { left: 8px; }
.cato-lightbox__nav--next { right: 8px; }

.cato-lightbox__count {
  position: absolute;
  bottom: 16px; left: 0; right: 0;
  margin: 0;
  text-align: center;
  color: rgba(255, 255, 255, .8);
  font-size: .8125rem;
}

@media (max-width: 640px) {
  .cato-lightbox__fig { inset: 52px 8px 52px; }
  .cato-lightbox__nav { width: 40px; height: 52px; font-size: 1.5rem; }
}


/* ============================================================================
   WHAT WE DO — post cards, and the article page
   ----------------------------------------------------------------------------
   /what-we-do is the blog on this site; there is no /blog. Two jobs here:
   the card grid on the index, and readable typography on a post.
   ============================================================================ */

/* --- The card grid ---------------------------------------------------------
   EVERY CARD IS THE SAME SHAPE, whatever shape its cover happens to be. The
   imported covers run from 200x71 brand logos to 1024x1536 phone portraits, and
   the old /blog let each one set its own row height — which is most of why that
   page looked broken. A fixed 16:10 media box with object-fit:cover means the
   grid is even no matter what the client uploads next. */
.cato-posts__grid {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
  gap: 28px;
}
@media (max-width: 700px) {
  .cato-posts__grid { grid-template-columns: 1fr; gap: 20px; }
}

.cato-post-card {
  display: flex;
  flex-direction: column;
  height: 100%;
  background: var(--cato-surface);
  border: 1px solid var(--cato-rule);
  border-radius: var(--cato-radius-lg);
  overflow: hidden;
  transition: transform var(--dur-base) var(--ease), box-shadow var(--dur-base) var(--ease);
}
.cato-post-card:hover {
  transform: translateY(-3px);
  box-shadow: var(--cato-shadow);
}
@media (prefers-reduced-motion: reduce) {
  .cato-post-card, .cato-post-card:hover { transition: none; transform: none; }
}

.cato-post-card__media {
  display: block;
  aspect-ratio: 16 / 10;
  background: var(--cato-bg);
  overflow: hidden;
}
.cato-post-card__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

/* A post with no cover gets a branded placeholder, not a collapsed box. */
.cato-post-card__placeholder {
  width: 100%; height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--cato-ink);
  color: rgba(255, 255, 255, .35);
}
.cato-post-card__placeholder .cato-icon { width: 2.5rem; height: 2.5rem; margin: 0; }

.cato-post-card__body {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 20px 22px 22px;
  flex: 1 1 auto;
}
.cato-post-card__meta {
  margin: 0;
  font-size: .8125rem;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--cato-ink-2);
}
.cato-post-card__title {
  margin: 0;
  font-family: var(--font-display);
  font-size: 1.3rem;
  line-height: 1.2;
  letter-spacing: .01em;
}
.cato-post-card__title a {
  color: var(--cato-ink);
  text-decoration: none;
}
/* The whole card lifts on hover, so the title carries the underline that says
   "this is the link". */
.cato-post-card:hover .cato-post-card__title a,
.cato-post-card__title a:focus-visible { color: var(--cato-brand); text-decoration: underline; }

.cato-post-card__excerpt {
  margin: 0;
  font-size: .9375rem;
  line-height: 1.55;
  color: var(--cato-ink-2);
}
.cato-post-card__more {
  margin: auto 0 0;          /* pinned to the bottom however short the excerpt */
  padding-top: 6px;
  font-family: var(--font-display);
  font-size: .875rem;
  letter-spacing: .02em;
  color: var(--cato-brand);
}

/* --- The article page ------------------------------------------------------
   The body was rendering at 14.4px with images at whatever width WordPress had
   baked into the markup (500px next to 1208px next to 672px). Both fixed here:
   a real reading size, and one width for every image. */
.post-body {
  font-size: 1.0625rem;      /* was inheriting 14.4px */
  line-height: 1.7;
  color: var(--color-text);
}
.post-body > * + * { margin-top: 1.1em; }

.post-body h2,
.post-body h3,
.post-body h4 {
  font-family: var(--font-display);
  letter-spacing: .01em;
  line-height: 1.15;
  margin-top: 2em;
  margin-bottom: .1em;
}
.post-body h2 { font-size: 1.75rem; }
.post-body h3 { font-size: 1.375rem; }
.post-body h4 { font-size: 1.125rem; }

.post-body p { margin: 0; }
.post-body ul,
.post-body ol { margin: 0; padding-left: 1.4em; }
.post-body li + li { margin-top: .35em; }

.post-body a { color: var(--color-accent-text); }

/* ONE WIDTH FOR EVERY IMAGE. The imported markup carries WordPress's own
   width/height attributes, which is why a post could show a 500px image, then a
   1208px one, then a 672px one, all in the same column. Overriding width here
   (and letting height follow) makes the article read as one piece. */
/* A BARE <img> KEEPS ITS OWN SIZE. Only images the importer judged to be real
   photographs (600px+ wide) are wrapped in <figure>, and only those fill the
   column. Forcing width:100% on everything blew a 200x71 brand logo up to 700px
   and, before the emoji were converted back to text, would have rendered a
   619-byte bicep emoji seven hundred pixels wide. */
.post-body img {
  max-width: 100%;
  height: auto;
  border-radius: var(--cato-radius);
}
.post-body figure {
  margin: 1.6em 0;
}
.post-body figure img {
  display: block;
  width: 100%;
  margin: 0;
}
.post-body figcaption {
  margin-top: .5em;
  font-size: .875rem;
  color: var(--color-text-muted);
  text-align: center;
}

.post-body blockquote {
  margin: 1.6em 0;
  padding: .2em 0 .2em 1.2em;
  border-left: 3px solid var(--cato-brand);
  color: var(--color-text-muted);
}

/* --- Related posts ---------------------------------------------------------
   Was a bare <ul> of blue links with a date floated right. */
.post-more { margin-top: 3.5rem; }
.post-more h2 {
  font-family: var(--font-display);
  font-size: 1.5rem;
  margin-bottom: 1rem;
}
.post-more__list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 2px;
  border-top: 1px solid var(--color-border);
}
.post-more__list li { border-bottom: 1px solid var(--color-border); }
.post-more__list a {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: .75rem;
  padding: .9rem .25rem;
  color: var(--color-text);
  text-decoration: none;
  font-family: var(--font-display);
  font-size: 1.0625rem;
  letter-spacing: .01em;
  transition: color var(--dur-fast) var(--ease), padding-left var(--dur-fast) var(--ease);
}
.post-more__list a:hover,
.post-more__list a:focus-visible {
  color: var(--cato-brand);
  padding-left: .6rem;
}
.post-more__list time {
  font-family: var(--font-sans);
  font-size: .8125rem;
  color: var(--color-text-muted);
  white-space: nowrap;
}
@media (prefers-reduced-motion: reduce) {
  .post-more__list a { transition: none; }
  .post-more__list a:hover { padding-left: .25rem; }
}

/* ===========================================================================
   BRANDS-ONLY INVENTORY (2026-09-24)
   /inventory lists brands; /inventory/{slug} is a brand page with a call button.
   =========================================================================== */

/* Category chips above the brand grid. They wrap on a phone rather than
   scrolling sideways, so every category stays visible. */
.shop-cats ul { display: flex; flex-wrap: wrap; justify-content: center; gap: .5rem; list-style: none; padding: 0; margin: 0 0 2rem; }
.shop-cats a { display: inline-flex; align-items: center; gap: .4rem; padding: .45rem .9rem; border: 1px solid var(--color-border); border-radius: 999px; text-decoration: none; color: var(--color-text); font-size: .9rem; background: var(--color-bg-alt); }
.shop-cats a:hover { border-color: var(--color-primary); color: var(--color-primary); }
.shop-cats a.is-active { background: var(--color-primary); border-color: var(--color-primary); color: #FFFFFF; }
.shop-cats a.is-active .shop-side__n { color: inherit; }

/* The whole brand card is one link: the title's ::after covers the card, so
   there is one tab stop per brand and a tap anywhere on it works. */
.shop-card--brand { position: relative; transition: border-color .15s, box-shadow .15s; }
.shop-card--brand:hover { border-color: var(--color-primary); box-shadow: var(--cato-shadow-sm); }
.shop-card--brand .shop-card__link::after { content: ""; position: absolute; inset: 0; }
.shop-card--brand .shop-card__link:focus-visible { outline: none; }
.shop-card--brand:focus-within { outline: 3px solid var(--color-primary); outline-offset: 2px; }
.shop-card__more { margin-top: auto; padding-top: .5rem; font-size: .875rem; font-weight: 600; color: var(--color-primary); }

.shop-brand__about p { max-width: 70ch; }

/* The call band that closes every brand page. */
.shop-callband { margin-top: 3rem; padding: 2rem 1.5rem; text-align: center; background: var(--color-bg-alt); border: 1px solid var(--color-border); border-radius: var(--cato-radius-lg, 14px); }
.shop-callband h2 { margin: 0 0 .5rem; }
.shop-callband p { margin: 0 auto 1.25rem; max-width: 46ch; color: var(--color-text-muted); }
.shop-call { white-space: nowrap; }

/* Brand page hero: most brand images are wide logos (316x113). Fit them inside
   a fixed box instead of stretching them to the column width. */
.shop-pdp--brand .shop-pdp__img { aspect-ratio: 4 / 3; object-fit: contain; padding: 2rem; background: #FFFFFF; }

/* Imported blurbs run to eight lines; keep brand cards level at four. */
.shop-card--brand .shop-card__blurb { display: -webkit-box; -webkit-line-clamp: 4; line-clamp: 4; -webkit-box-orient: vertical; overflow: hidden; }

/* On a phone a square logo box makes each brand a full screen of scrolling. */
@media (max-width: 40rem) { .shop-card--brand .shop-card__media { aspect-ratio: 16 / 9; } }

/* Brand page sections (2026-09-24). */
.shop-facts { list-style: none; padding: 0; margin: 1rem 0 0; display: flex; flex-wrap: wrap; gap: .5rem; }
.shop-facts li { display: inline-flex; align-items: center; gap: .4rem; padding: .35rem .75rem; border-radius: 999px; background: #EEF0FF; color: var(--color-text); font-size: .875rem; font-weight: 500; }
.shop-facts li::before { content: ""; width: .55rem; height: .3rem; border-left: 2px solid var(--color-primary); border-bottom: 2px solid var(--color-primary); transform: rotate(-45deg) translateY(-1px); }

.shop-lines, .shop-photos { margin-top: 3rem; }
.shop-lines > h2 { margin: 0 0 1.25rem; }
.shop-lines__grid { list-style: none; padding: 0; margin: 0; display: grid; grid-template-columns: repeat(auto-fill, minmax(min(16rem, 100%), 1fr)); gap: 1rem; }
.shop-lines__item { padding: 1.1rem 1.25rem; background: var(--color-bg-alt); border: 1px solid var(--color-border); border-left: 4px solid var(--color-primary); border-radius: 10px; }
.shop-lines__item h3 { margin: 0; font-size: 1.1rem; }
.shop-lines__item p { margin: .35rem 0 0; font-size: .9375rem; color: var(--color-text-muted); }

.shop-photos__grid { list-style: none; padding: 0; margin: 0; display: grid; grid-template-columns: repeat(auto-fill, minmax(min(14rem, 100%), 1fr)); gap: .75rem; }
.shop-photos__grid img { width: 100%; height: 100%; aspect-ratio: 4 / 3; object-fit: cover; border-radius: 10px; background: var(--color-bg-sunk); }

/* Admin > Blog: the "share it on social" offer after publishing. */
.sm-offer { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--sp-3) var(--sp-5); margin-bottom: var(--sp-5);
  border-color: var(--color-primary); box-shadow: inset 0 0 0 1px var(--color-primary); }
.sm-offer h2 { margin: 0 0 .25rem; }
.sm-offer p { margin: 0; max-width: 60ch; }

/* Social: a video post (2026-10-26). The thumbnail matches a photo's; the
   preview matches .pv__one img. A layout rule on these beats the browser's own
   [hidden], so it is said again here. */
.sm-photos video { width: 104px; height: 80px; object-fit: cover; border-radius: var(--radius-sm); background: #000; display: block; }
.sm-photos li[hidden], .sm-video[hidden], .sm-video__cover[hidden], .sm-video progress[hidden] { display: none; }
.pv__one video { display: block; width: 100%; height: auto; max-height: 32rem; background: #000; }
.sm-video { display: grid; gap: .4rem; margin: 0 0 .75rem; }
.sm-video progress { width: 100%; }
.sm-video__cover { display: grid; gap: .25rem; }
.sm-video__cover input[type="range"] { width: 100%; }
