/* =====================================================================
   DEFENCE STREET — public website styles
   ===================================================================== */

/* ---------- base ---------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }

html { scroll-behavior: smooth; }

body {
  font-family: var(--ds-font-body);
  color: var(--ds-text);
  background: var(--ds-bg);
  font-size: 15.5px;
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

h1, h2, h3, h4, h5, .display-font {
  font-family: var(--ds-font-display);
  font-weight: 700;
  letter-spacing: -.01em;
  color: var(--ds-navy-800);
  line-height: 1.15;
}

h1 { font-size: clamp(2rem, 4.2vw, 3.4rem); font-weight: 800; }
h2 { font-size: clamp(1.6rem, 2.8vw, 2.4rem); }
h3 { font-size: clamp(1.25rem, 2vw, 1.6rem); }

a { color: var(--ds-primary); text-decoration: none; transition: color .2s var(--ds-ease); }
a:hover { color: var(--ds-primary-dark); }

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

.container-ds { width: 100%; max-width: var(--ds-container); margin-inline: auto; padding-inline: 1rem; }

::selection { background: var(--ds-blue-100); color: var(--ds-navy-800); }

/* Scrollbar */
::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-track { background: var(--ds-steel-100); }
::-webkit-scrollbar-thumb { background: var(--ds-steel-300); border-radius: 20px; }
::-webkit-scrollbar-thumb:hover { background: var(--ds-steel-500); }

/* ---------- utilities ------------------------------------------------ */
.text-gradient {
  background: var(--ds-grad-blue);
  -webkit-background-clip: text; background-clip: text;
  -webkit-text-fill-color: transparent;
}
.text-gold { color: var(--ds-accent); }
.accent { color: var(--ds-accent); }
.bg-soft { background: var(--ds-bg-soft); }
.bg-navy { background: var(--ds-navy-800); color: #fff; }
.shadow-ds { box-shadow: var(--ds-shadow); }
.rounded-ds { border-radius: var(--ds-radius); }
/* Section rhythm. The gaps used to run to 5.5rem, which pushed the page to
   nearly 8,000px and left large empty bands between blocks on a wide screen. */
.section { padding: clamp(2rem, 3.4vw, 3.25rem) 0; }
.section-tight { padding: clamp(1.5rem, 2.6vw, 2.25rem) 0; }
.muted { color: var(--ds-muted); }
.fw-800 { font-weight: 800; }

.section-head { margin-bottom: 1.4rem; }
.section-head .eyebrow {
  display: inline-flex; align-items: center; gap: .45rem;
  font-size: .74rem; font-weight: 700; letter-spacing: .13em; text-transform: uppercase;
  color: var(--ds-primary); background: var(--ds-blue-050);
  border: 1px solid var(--ds-blue-100);
  padding: .32rem .75rem; border-radius: 999px; margin-bottom: .7rem;
}
.section-head h2 { margin: 0 0 .35rem; }
.section-head p { color: var(--ds-muted); margin: 0; max-width: 62ch; }

.link-more {
  font-weight: 600; font-size: .92rem; display: inline-flex; align-items: center; gap: .35rem;
}
.link-more i { transition: transform .25s var(--ds-ease); }
.link-more:hover i { transform: translateX(4px); }

/* ---------- buttons -------------------------------------------------- */
.btn { font-weight: 600; border-radius: var(--ds-radius-sm); transition: all .25s var(--ds-ease); }

.btn-ds {
  background: var(--ds-grad-blue); color: #fff; border: none;
  padding: .68rem 1.4rem; box-shadow: 0 6px 18px rgba(11, 87, 208, .28);
  position: relative; overflow: hidden;
}
.btn-ds:hover { color: #fff; transform: translateY(-2px); box-shadow: 0 12px 26px rgba(11, 87, 208, .36); }
.btn-ds::after {
  content: ''; position: absolute; inset: 0; left: -120%;
  background: linear-gradient(115deg, transparent, rgba(255,255,255,.35), transparent);
  transition: left .6s var(--ds-ease);
}
.btn-ds:hover::after { left: 120%; }

.btn-gold {
  background: var(--ds-grad-gold); color: var(--ds-navy-800); border: none;
  padding: .68rem 1.4rem; font-weight: 700;
  box-shadow: 0 6px 18px rgba(245, 179, 1, .32);
}
.btn-gold:hover { color: var(--ds-navy-900); transform: translateY(-2px); box-shadow: 0 12px 26px rgba(245, 179, 1, .42); }

.btn-ghost {
  background: transparent; border: 1.5px solid var(--ds-border); color: var(--ds-text);
  padding: .62rem 1.2rem;
}
.btn-ghost:hover { border-color: var(--ds-primary); color: var(--ds-primary); background: var(--ds-blue-050); }

.btn-ghost-light {
  background: rgba(255,255,255,.08); border: 1.5px solid rgba(255,255,255,.25); color: #fff;
  padding: .62rem 1.2rem; backdrop-filter: blur(6px);
}
.btn-ghost-light:hover { background: rgba(255,255,255,.18); color: #fff; border-color: rgba(255,255,255,.5); }

.btn-icon {
  width: 38px; height: 38px; display: inline-grid; place-items: center;
  border-radius: 10px; border: 1px solid var(--ds-border); background: #fff; color: var(--ds-steel-700);
}
.btn-icon:hover { border-color: var(--ds-primary); color: var(--ds-primary); background: var(--ds-blue-050); }
.btn-icon.active { background: var(--ds-primary); border-color: var(--ds-primary); color: #fff; }

/* ---------- badges --------------------------------------------------- */
.badge-soft-primary  { background: var(--ds-blue-050); color: var(--ds-primary); border: 1px solid var(--ds-blue-100); }
.badge-soft-success  { background: #ecfdf5; color: var(--ds-success); border: 1px solid #bbf7d0; }
.badge-soft-warning  { background: #fffbeb; color: var(--ds-warning); border: 1px solid #fde68a; }
.badge-soft-danger   { background: #fef2f2; color: var(--ds-danger); border: 1px solid #fecaca; }
.badge-soft-info     { background: #f0f9ff; color: var(--ds-info); border: 1px solid #bae6fd; }
.badge-soft-secondary{ background: var(--ds-steel-100); color: var(--ds-steel-700); border: 1px solid var(--ds-steel-300); }
.badge-soft-dark     { background: #e2e8f0; color: var(--ds-navy-800); border: 1px solid #cbd5e1; }
[class^="badge-soft-"], [class*=" badge-soft-"] {
  font-weight: 600; font-size: .72rem; padding: .3rem .6rem; border-radius: 999px; display: inline-block;
}

.chip {
  display: inline-flex; align-items: center; gap: .35rem;
  font-size: .76rem; font-weight: 600; color: var(--ds-steel-700);
  background: var(--ds-steel-100); border: 1px solid var(--ds-border);
  padding: .28rem .68rem; border-radius: 999px;
  transition: all .2s var(--ds-ease);
}
a.chip:hover { background: var(--ds-blue-050); border-color: var(--ds-blue-100); color: var(--ds-primary); }

.verified-badge {
  display: inline-grid; place-items: center; width: 20px; height: 20px;
  background: var(--ds-blue-600); color: #fff; border-radius: 50%; font-size: .62rem;
  vertical-align: middle;
}
.flag { font-size: 1.05em; line-height: 1; }

/* ---------- header (3 parts: top strip / main bar / nav bar) ----------- */
.ds-header {
  position: sticky; top: calc(-1 * var(--hdr-top-h)); z-index: 1030;
  background: #fff;
  /* The header's own bottom edge is the dark nav bar, so a light hairline
     here reads as a white line against a dark hero. Keep it dark. */
  box-shadow: 0 1px 0 rgba(5, 13, 28, .55);
  transition: box-shadow .3s var(--ds-ease);
}
.ds-header.is-scrolled { box-shadow: 0 8px 28px rgba(15, 23, 42, .10); }

/* --- 1. top strip ------------------------------------------------------ */
.hdr-top {
  background: var(--ds-navy-900); color: rgba(255,255,255,.66);
  font-size: .78rem; height: var(--hdr-top-h); overflow: hidden;
}
.hdr-top-inner {
  height: 100%; display: flex; align-items: center; justify-content: space-between; gap: 1rem;
}
.hdr-top-left, .hdr-top-right { display: flex; align-items: center; gap: 1.15rem; min-width: 0; }
.hdr-top a { color: rgba(255,255,255,.66); white-space: nowrap; transition: color .2s var(--ds-ease); }
.hdr-top a:hover { color: var(--ds-accent); }
.hdr-top i { opacity: .75; margin-right: .18rem; }
.hdr-tagline {
  color: rgba(255,255,255,.5); text-transform: uppercase;
  letter-spacing: .08em; font-size: .7rem; font-weight: 600; white-space: nowrap;
}
.hdr-tagline i { color: var(--ds-accent); opacity: 1; }
.hdr-sep { width: 1px; height: 15px; background: rgba(255,255,255,.16); }
.hdr-links { display: flex; gap: .55rem; }
.hdr-links a { font-size: .92rem; }
@media (max-width: 1199px) { .hdr-tagline, .hdr-top-right a { display: none; } }
@media (max-width: 991px)  { .hdr-top { display: none; } }

/* --- 2. main bar ------------------------------------------------------- */
.hdr-main { background: #fff; height: var(--hdr-main-h); transition: height .3s var(--ds-ease); }
.hdr-main-inner { height: 100%; display: flex; align-items: center; gap: 1.4rem; }

.ds-logo { display: flex; align-items: center; gap: .6rem; flex: none; }
.ds-logo img { height: 46px; width: auto; transition: height .3s var(--ds-ease); }
.ds-logo .wordmark {
  font-family: var(--ds-font-display); font-weight: 800; font-size: 1.42rem;
  line-height: .95; letter-spacing: .01em; color: var(--ds-navy-800); text-transform: uppercase;
}
.ds-logo .wordmark span { display: block; color: var(--ds-primary); }

/* search */
.hdr-search {
  flex: 1 1 auto; max-width: 640px; display: flex; align-items: stretch;
  border: 2px solid var(--ds-steel-300); border-radius: 999px; background: #fff;
  transition: border-color .25s var(--ds-ease), box-shadow .25s var(--ds-ease);
}
.hdr-search:focus-within { border-color: var(--ds-primary); box-shadow: var(--ds-shadow-glow); }
.hdr-scope {
  border: none; background: transparent; font-size: .84rem; font-weight: 600;
  color: var(--ds-steel-700); padding: 0 .5rem 0 1.05rem; border-radius: 999px 0 0 999px;
  cursor: pointer; -webkit-appearance: none; appearance: none;
  background-image: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%237b8ba3'%3E%3Cpath d='M4 6l4 4 4-4z'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right .1rem center; background-size: 15px;
  padding-right: 1.15rem;
}
.hdr-scope:focus { outline: none; }
.hdr-search-field { position: relative; flex: 1; display: flex; align-items: center; min-width: 0; }
.hdr-search-field::before {
  content: ''; position: absolute; left: 0; top: 20%; bottom: 20%; width: 1px; background: var(--ds-steel-300);
}
.hdr-search-field .bi-search { position: absolute; left: 1rem; color: var(--ds-steel-500); font-size: .95rem; }
.hdr-search-field input {
  width: 100%; border: none; background: transparent; font-size: .92rem;
  padding: .62rem .8rem .62rem 2.5rem;
}
.hdr-search-field input:focus { outline: none; }
.hdr-search-field input::-webkit-search-cancel-button { -webkit-appearance: none; }
.hdr-search-btn {
  border: none; border-radius: 999px; margin: 4px; padding: 0 1.25rem;
  background: var(--ds-grad-blue); color: #fff; font-weight: 700; font-size: .88rem;
  display: inline-flex; align-items: center; gap: .4rem;
  transition: filter .2s var(--ds-ease), transform .2s var(--ds-ease);
}
.hdr-search-btn:hover { filter: brightness(1.08); transform: translateY(-1px); }
.hdr-search-btn i { font-size: .95rem; }

.hdr-actions { display: flex; align-items: center; gap: .55rem; margin-left: auto; flex: none; }
.hdr-cta { white-space: nowrap; border-radius: 999px; }
.hdr-login { border-radius: 999px; white-space: nowrap; }
.hdr-burger {
  border: 1px solid var(--ds-border); background: #fff; border-radius: 10px;
  width: 42px; height: 42px; display: grid; place-items: center;
  font-size: 1.35rem; color: var(--ds-navy-800); line-height: 1;
}
.hdr-burger[aria-expanded="true"] { background: var(--ds-blue-050); color: var(--ds-primary); }

.header-action {
  display: inline-flex; align-items: center; justify-content: center;
  width: 42px; height: 42px; border-radius: 10px; color: var(--ds-steel-700);
  position: relative; transition: all .2s var(--ds-ease);
}
.header-action:hover { background: var(--ds-steel-100); color: var(--ds-primary); }
.header-action .count {
  position: absolute; top: 2px; right: 2px; min-width: 17px; height: 17px;
  background: var(--ds-accent); color: var(--ds-navy-900);
  font-size: .63rem; font-weight: 800; border-radius: 999px;
  display: grid; place-items: center; padding-inline: 4px;
}

/* --- 3. bottom nav bar ------------------------------------------------- */
.hdr-bottom {
  background: var(--ds-navy-800);
  background-image: linear-gradient(90deg, var(--ds-navy-800), var(--ds-navy-700) 55%, var(--ds-navy-600));
  height: var(--hdr-nav-h);
}
.hdr-bottom-inner { display: flex; align-items: stretch; gap: .4rem; height: 100%; min-width: 0; }

/* "All Categories" mega trigger */
.hdr-mega-wrap { flex: none; display: flex; }
.hdr-mega-btn {
  display: inline-flex; align-items: center; gap: .55rem;
  border: none; background: var(--ds-grad-blue); color: #fff;
  font-weight: 700; font-size: .88rem; padding: 0 1.15rem; height: var(--hdr-nav-h);
  letter-spacing: .01em; white-space: nowrap;
}
.hdr-mega-btn .chev { font-size: .72rem; transition: transform .28s var(--ds-ease); }
.hdr-mega-btn[aria-expanded="true"] .chev { transform: rotate(180deg); }
.hdr-mega-btn:hover { filter: brightness(1.1); }

.hdr-mega {
  border: none; border-radius: 0 0 var(--ds-radius) var(--ds-radius);
  box-shadow: var(--ds-shadow-lg); padding: 1.5rem;
  width: min(920px, calc(100vw - 2rem));
  grid-template-columns: repeat(3, 1fr); gap: 1.6rem;
}
.hdr-mega.show { display: grid; animation: dsFadeDown .24s var(--ds-ease-out); }
.hdr-mega-col h6 {
  font-size: .7rem; text-transform: uppercase; letter-spacing: .1em; font-weight: 800;
  color: var(--ds-steel-500); margin-bottom: .7rem; font-family: var(--ds-font-body);
}
.hdr-mega-col ul { list-style: none; margin: 0; padding: 0; }
.hdr-mega-col li + li { margin-top: .1rem; }
.hdr-mega-col a {
  display: flex; align-items: center; gap: .6rem; padding: .42rem .55rem;
  border-radius: 8px; font-size: .88rem; font-weight: 500; color: var(--ds-text);
  transition: background .18s var(--ds-ease), color .18s var(--ds-ease);
}
.hdr-mega-col a:hover { background: var(--ds-blue-050); color: var(--ds-primary); }
.hdr-mega-col a i { color: var(--ds-steel-500); width: 17px; flex: none; font-size: .95rem; }
.hdr-mega-col a:hover i { color: var(--ds-primary); }
.hdr-mega-col a span { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.hdr-mega-col a em {
  font-style: normal; font-size: .7rem; font-weight: 700; color: var(--ds-steel-500);
  background: var(--ds-steel-100); border-radius: 999px; padding: .1rem .42rem;
}
.hdr-mega-all {
  display: inline-flex; align-items: center; gap: .35rem; margin-top: .7rem; padding-left: .55rem;
  font-size: .8rem; font-weight: 700; color: var(--ds-primary);
}
.hdr-mega-all i { transition: transform .22s var(--ds-ease); }
.hdr-mega-all:hover i { transform: translateX(3px); }
.hdr-mega-promo { border-left: 1px solid var(--ds-border); padding-left: 1.6rem; }
@media (max-width: 991px) { .hdr-mega-wrap { display: none; } }

/* nav row */
.hdr-nav-collapse { flex: 1; min-width: 0; display: flex; align-items: center; justify-content: space-between; gap: 1rem; }
@media (min-width: 992px) { .hdr-nav-collapse { display: flex !important; } }

.ds-nav {
  display: flex; align-items: center; list-style: none; margin: 0; padding: 0;
  flex-wrap: nowrap; min-width: 0; overflow-x: auto; scrollbar-width: none;
}
.ds-nav::-webkit-scrollbar { display: none; }
.ds-nav .nav-link {
  display: block; font-weight: 600; font-size: .89rem; color: rgba(255,255,255,.82);
  padding: 0 .8rem; line-height: var(--hdr-nav-h); position: relative; white-space: nowrap;
  transition: color .2s var(--ds-ease);
}
.ds-nav .nav-link::after {
  content: ''; position: absolute; left: .8rem; right: .8rem; bottom: 0; height: 3px;
  background: var(--ds-accent); border-radius: 3px 3px 0 0;
  transform: scaleX(0); transform-origin: left; transition: transform .3s var(--ds-ease);
}
.ds-nav .nav-link:hover, .ds-nav .nav-link.active { color: #fff; }
.ds-nav .nav-link:hover::after, .ds-nav .nav-link.active::after { transform: scaleX(1); }

.hdr-bottom-right { display: flex; align-items: center; gap: .3rem; margin-left: auto; }
.hdr-bottom-right a {
  display: inline-flex; align-items: center; gap: .4rem; white-space: nowrap;
  font-size: .82rem; font-weight: 600; color: rgba(255,255,255,.72);
  padding: .34rem .7rem; border-radius: 999px; border: 1px solid rgba(255,255,255,.16);
  transition: all .22s var(--ds-ease);
}
.hdr-bottom-right a:hover { color: var(--ds-navy-900); background: var(--ds-accent); border-color: var(--ds-accent); }
.hdr-bottom-right i { font-size: .9rem; }

/* --- scrolled state: the top strip rolls up out of the way --------------
   The main + nav bars keep their exact height so --ds-header-h stays true
   for every sticky element that offsets against it. */
.ds-header.is-scrolled .ds-logo img { height: 40px; }

/* --- mobile ------------------------------------------------------------ */
/* --- mobile header ------------------------------------------------------
   Logo on the left, then matching square icon buttons on the right, and the
   search on its own row. Everything shares one size and one corner radius so
   the bar reads as a set rather than a row of mismatched shapes. */
@media (max-width: 991px) {
  .hdr-main { height: auto; }
  .hdr-main-inner { gap: .5rem; flex-wrap: wrap; padding-block: .55rem; align-items: center; }

  .hdr-actions { gap: .4rem; }
  .hdr-actions .hdr-login,
  .hdr-actions .hdr-burger,
  .hdr-actions .header-action {
    width: 42px; height: 42px; min-width: 42px; padding: 0; border-radius: 12px;
    display: inline-grid; place-items: center; font-size: 1.12rem; line-height: 1;
  }
  .hdr-actions .hdr-login {
    background: var(--ds-grad-blue); border: 0; color: #fff;
    box-shadow: 0 5px 14px rgba(11, 87, 208, .3);
  }
  .hdr-actions .hdr-login i { margin: 0 !important; font-size: 1.12rem; }
  .hdr-actions .hdr-burger,
  .hdr-actions .header-action {
    background: #fff; border: 1px solid var(--ds-border); color: var(--ds-steel-700);
  }
  .hdr-actions .hdr-burger[aria-expanded="true"] {
    background: var(--ds-blue-050); border-color: var(--ds-blue-400); color: var(--ds-primary);
  }
  .hdr-actions .dropdown .btn-ghost { padding: .3rem; border-radius: 12px; }

  /* search sits on its own row, squared off to match the buttons */
  .hdr-search {
    order: 3; flex-basis: 100%; max-width: none;
    border-radius: 12px; border-width: 1px; border-color: var(--ds-border);
    background: var(--ds-steel-100);
  }
  .hdr-search:focus-within { background: #fff; border-color: var(--ds-primary); }
  .hdr-search-field input { padding-block: .6rem; font-size: .93rem; }
  .hdr-search-btn { margin: 3px; border-radius: 9px; padding-inline: .85rem; }
  .hdr-search-btn span { display: none; }
}
/* On a phone the scope picker eats the room the search field needs. */
@media (max-width: 575px) {
  .hdr-scope { display: none; }
  .hdr-search-field::before { display: none; }
  .hdr-search-field .bi-search { left: .85rem; }
  .hdr-search-field input { padding-left: 2.35rem; }
}
@media (max-width: 991px) {
  .ds-logo img { height: 34px; }
  .ds-logo .wordmark { font-size: 1.12rem; }

  /* no white sliver under the bar while the menu is closed */
  .hdr-bottom { background: #fff; height: auto; }
  .hdr-bottom-inner:not(:has(.show)):not(:has(.collapsing)) { min-height: 0; }
  .hdr-bottom-inner { display: block; }
  .hdr-nav-collapse { display: none; flex-direction: column; align-items: stretch; }
  .hdr-nav-collapse.show, .hdr-nav-collapse.collapsing { display: flex; }
  .ds-nav { flex-direction: column; align-items: stretch; padding: .5rem 0 1rem; }
  .ds-nav .nav-link {
    color: var(--ds-text); line-height: 1.4; padding: .75rem .25rem;
    border-bottom: 1px solid var(--ds-steel-100);
  }
  .ds-nav .nav-link::after { display: none; }
  .ds-nav .nav-link.active { color: var(--ds-primary); }
}

/* Mega dropdown */
.ds-dropdown {
  border: 1px solid var(--ds-border); border-radius: var(--ds-radius);
  box-shadow: var(--ds-shadow-lg); padding: .6rem; min-width: 240px;
  animation: dsFadeDown .22s var(--ds-ease-out);
}
.ds-dropdown .dropdown-item {
  border-radius: 8px; font-weight: 500; font-size: .9rem; padding: .5rem .7rem;
  display: flex; align-items: center; gap: .6rem;
}
.ds-dropdown .dropdown-item:hover { background: var(--ds-blue-050); color: var(--ds-primary); }
.ds-dropdown .dropdown-item i { color: var(--ds-steel-500); width: 18px; }
.ds-dropdown .dropdown-item:hover i { color: var(--ds-primary); }

@keyframes dsFadeDown { from { opacity: 0; transform: translateY(-8px); } to { opacity: 1; transform: none; } }

/* Header search */
.header-search { position: relative; flex: 1; max-width: 420px; }
.header-search input {
  border-radius: 999px; border: 1px solid var(--ds-border); background: var(--ds-steel-100);
  padding: .55rem 1rem .55rem 2.4rem; font-size: .9rem; width: 100%;
  transition: all .25s var(--ds-ease);
}
.header-search input:focus {
  outline: none; background: #fff; border-color: var(--ds-blue-400); box-shadow: var(--ds-shadow-glow);
}
.header-search .bi-search {
  position: absolute; left: .9rem; top: 50%; transform: translateY(-50%); color: var(--ds-steel-500);
}

.search-suggest {
  position: absolute; top: calc(100% + .5rem); left: 0; right: 0; z-index: 1040;
  background: #fff; border: 1px solid var(--ds-border); border-radius: var(--ds-radius);
  box-shadow: var(--ds-shadow-lg); overflow: hidden; max-height: 420px; overflow-y: auto;
  animation: dsFadeDown .2s var(--ds-ease-out);
}
.search-suggest a {
  display: flex; align-items: center; gap: .7rem; padding: .6rem .85rem;
  border-bottom: 1px solid var(--ds-steel-100); color: var(--ds-text);
}
.search-suggest a:last-child { border-bottom: none; }
.search-suggest a:hover { background: var(--ds-blue-050); }
.search-suggest img, .search-suggest .ph {
  width: 34px; height: 34px; object-fit: contain; border-radius: 8px;
  background: var(--ds-steel-100); flex: none;
}
.search-suggest .type {
  margin-left: auto; font-size: .68rem; font-weight: 700; text-transform: uppercase;
  letter-spacing: .05em; color: var(--ds-steel-500);
}

/* ---------- hero ----------------------------------------------------- */
.hero {
  position: relative; overflow: hidden; color: #fff;
  background: var(--ds-grad-hero);
  padding: clamp(4rem, 9vw, 7.5rem) 0 clamp(3rem, 6vw, 5rem);
  padding-top: clamp(3rem, 7vw, 6rem);
}
.hero::before {
  content: ''; position: absolute; inset: 0;
  background-image: radial-gradient(circle at 18% 22%, rgba(79, 147, 255, .28), transparent 42%),
                    radial-gradient(circle at 82% 12%, rgba(245, 179, 1, .16), transparent 40%),
                    radial-gradient(circle at 60% 88%, rgba(11, 87, 208, .3), transparent 45%);
  animation: heroDrift 22s ease-in-out infinite alternate;
}
@keyframes heroDrift {
  from { transform: scale(1) translate(0, 0); }
  to   { transform: scale(1.12) translate(-2%, 2%); }
}
.hero .hero-media {
  position: absolute; inset: 0; object-fit: cover; width: 100%; height: 100%;
  opacity: .62; z-index: 0;
}
.hero .hero-scrim {
  position: absolute; inset: 0; z-index: 1;
  background: linear-gradient(95deg, rgba(5,13,28,.93) 0%, rgba(5,13,28,.78) 42%, rgba(5,13,28,.42) 78%, rgba(11,63,168,.35) 100%);
}
/* the animated radial wash sits under the photo, not over it */
.hero:has(.hero-media)::before { opacity: .55; z-index: 0; }
.hero > .container-ds, .hero > .container { position: relative; z-index: 2; }

.hero h1 { color: #fff; max-width: 18ch; margin-bottom: 1rem; }
.hero h1 .accent { color: var(--ds-gold-500); display: block; }
.hero .lead { color: rgba(255,255,255,.82); font-size: 1.06rem; max-width: 58ch; }

/* Grid overlay for a technical feel */
.hero .grid-overlay {
  position: absolute; inset: 0; opacity: .09; pointer-events: none;
  background-image: linear-gradient(rgba(255,255,255,.6) 1px, transparent 1px),
                    linear-gradient(90deg, rgba(255,255,255,.6) 1px, transparent 1px);
  background-size: 56px 56px;
  mask-image: radial-gradient(ellipse at 50% 40%, #000 20%, transparent 78%);
  -webkit-mask-image: radial-gradient(ellipse at 50% 40%, #000 20%, transparent 78%);
}

/* Hero search box */
.hero-search { max-width: 720px; }
.hero-search .search-tabs { display: flex; gap: .35rem; margin-bottom: .7rem; flex-wrap: wrap; }
.hero-search .search-tabs button {
  border: 1px solid rgba(255,255,255,.22); background: rgba(255,255,255,.08); color: rgba(255,255,255,.85);
  font-size: .82rem; font-weight: 600; padding: .35rem .95rem; border-radius: 999px;
  transition: all .22s var(--ds-ease); backdrop-filter: blur(6px);
}
.hero-search .search-tabs button:hover { background: rgba(255,255,255,.18); color: #fff; }
.hero-search .search-tabs button.active {
  background: var(--ds-blue-600); border-color: var(--ds-blue-500); color: #fff;
  box-shadow: 0 4px 16px rgba(11, 87, 208, .45);
}
.hero-search .search-field {
  display: flex; align-items: center; gap: .5rem; background: #fff;
  border-radius: 999px; padding: .38rem .38rem .38rem 1.1rem;
  box-shadow: 0 18px 44px rgba(0,0,0,.32);
}
.hero-search .search-field i.bi-search { color: var(--ds-steel-500); }
.hero-search .search-field input {
  border: none; outline: none; flex: 1; font-size: .98rem; padding: .55rem 0; color: var(--ds-text);
  background: transparent; min-width: 0;
}
.hero-search .search-field button {
  border: none; border-radius: 999px; padding: .6rem 1.5rem; font-weight: 700;
  background: var(--ds-grad-gold); color: var(--ds-navy-900); white-space: nowrap;
  transition: all .22s var(--ds-ease);
}
.hero-search .search-field button:hover { filter: brightness(1.06); transform: translateX(1px); }

.hero-hints { margin-top: .8rem; font-size: .84rem; color: rgba(255,255,255,.6); }
.hero-hints a { color: rgba(255,255,255,.86); border-bottom: 1px dashed rgba(255,255,255,.3); }
.hero-hints a:hover { color: #fff; border-color: #fff; }

/* Stat strip */
.stat-strip { display: grid; grid-template-columns: repeat(4, 1fr); gap: 1rem; margin-top: 2.6rem; }
.stat-card {
  display: flex; align-items: center; gap: .9rem;
  background: rgba(255,255,255,.07); border: 1px solid rgba(255,255,255,.14);
  border-radius: var(--ds-radius); padding: 1rem 1.1rem; backdrop-filter: blur(10px);
  transition: transform .3s var(--ds-ease), background .3s var(--ds-ease);
}
.stat-card:hover { transform: translateY(-4px); background: rgba(255,255,255,.13); }
.stat-card .icon {
  width: 44px; height: 44px; flex: none; border-radius: 12px; display: grid; place-items: center;
  font-size: 1.2rem; color: #fff;
}
.stat-card .value {
  font-family: var(--ds-font-display); font-size: 1.65rem; font-weight: 800; line-height: 1; color: #fff;
}
.stat-card .label { font-size: .8rem; color: rgba(255,255,255,.68); margin-top: .15rem; }

@media (max-width: 991px) { .stat-strip { grid-template-columns: repeat(2, 1fr); } }
/* Two per row on a phone. One per row turned four short facts into four
   full-width bands and pushed everything below them off the first screen. */
@media (max-width: 480px) {
  .stat-strip { grid-template-columns: repeat(2, 1fr); gap: .6rem; }
  .stat-card { padding: .7rem; gap: .6rem; }
  .stat-card .icon { width: 34px; height: 34px; font-size: .95rem; }
  .stat-card .value { font-size: 1.25rem; }
  .stat-card .label { font-size: .7rem; line-height: 1.25; }
}

/* ---------- page banner (inner pages) --------------------------------- */
.page-masthead {
  position: relative; overflow: hidden; color: #fff;
  padding: clamp(2.6rem, 6vw, 4.2rem) 0 clamp(2rem, 4vw, 3rem);
  padding-top: clamp(2rem, 4vw, 3rem);
  background: var(--ds-grad-hero);
}
.page-masthead.purple { background: linear-gradient(120deg, #2e1065, #5b21b6 55%, #7c3aed); }
.page-masthead.green  { background: linear-gradient(120deg, #052e16, #14532d 55%, #15803d); }
.page-masthead.gold   { background: linear-gradient(120deg, #451a03, #92400e 55%, #d97706); }
.page-masthead.teal   { background: linear-gradient(120deg, #042f2e, #115e59 55%, #0d9488); }
.page-masthead::after {
  content: ''; position: absolute; inset: 0; opacity: .1; z-index: 1;
  background-image: radial-gradient(circle at 80% 20%, #fff, transparent 45%);
}
/* optional photograph behind the gradient */
.page-masthead .pb-media {
  position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover;
  z-index: 0; opacity: .5;
}
.page-masthead .pb-scrim {
  position: absolute; inset: 0; z-index: 1; display: block;
  background: linear-gradient(100deg, rgba(5,13,28,.9) 0%, rgba(5,13,28,.6) 55%, rgba(5,13,28,.35) 100%);
}
.page-masthead.purple .pb-scrim { background: linear-gradient(100deg, rgba(46,16,101,.92), rgba(91,33,182,.55)); }
.page-masthead.gold   .pb-scrim { background: linear-gradient(100deg, rgba(69,26,3,.92), rgba(146,64,14,.55)); }
.page-masthead.teal   .pb-scrim { background: linear-gradient(100deg, rgba(4,47,46,.92), rgba(17,94,89,.55)); }
.page-masthead.green  .pb-scrim { background: linear-gradient(100deg, rgba(5,46,22,.92), rgba(20,83,45,.55)); }
.page-masthead .container-ds, .page-masthead .container { position: relative; z-index: 2; }
.page-masthead h1 { color: #fff; margin-bottom: .4rem; }
.page-masthead p { color: rgba(255,255,255,.78); margin: 0; max-width: 62ch; }

.ds-breadcrumb {
  background: transparent; padding: 0; margin-bottom: .9rem; font-size: .85rem;
}
.ds-breadcrumb .breadcrumb-item, .ds-breadcrumb a { color: rgba(255,255,255,.66); }
.ds-breadcrumb a:hover { color: #fff; }
.ds-breadcrumb .breadcrumb-item.active { color: rgba(255,255,255,.95); }
.ds-breadcrumb .breadcrumb-item + .breadcrumb-item::before { color: rgba(255,255,255,.4); }
.breadcrumb-light .ds-breadcrumb .breadcrumb-item,
.breadcrumb-light .ds-breadcrumb a { color: var(--ds-muted); }
.breadcrumb-light .ds-breadcrumb .breadcrumb-item.active { color: var(--ds-text); }

/* ---------- cards ----------------------------------------------------- */
.ds-card {
  background: #fff; border: 1px solid var(--ds-border); border-radius: var(--ds-radius);
  overflow: hidden; height: 100%; position: relative;
  transition: transform .35s var(--ds-ease), box-shadow .35s var(--ds-ease), border-color .35s var(--ds-ease);
}
.ds-card:hover {
  transform: translateY(-6px); box-shadow: var(--ds-shadow-lg); border-color: var(--ds-blue-100);
}
.ds-card::before {
  content: ''; position: absolute; top: 0; left: 0; right: 0; height: 3px;
  background: var(--ds-grad-blue); transform: scaleX(0); transform-origin: left;
  transition: transform .4s var(--ds-ease);
}
.ds-card:hover::before { transform: scaleX(1); }

.ds-card .card-body { padding: 1.15rem; }

/* Company card */
.company-card h3 {
  font-size: 1.02rem; font-family: var(--ds-font-body); font-weight: 700;
  margin: 0 0 .3rem; line-height: 1.35;
}
.company-card h3 a { color: var(--ds-navy-800); }
.company-card h3 a:hover { color: var(--ds-primary); }
.company-card .card-foot {
  border-top: 1px solid var(--ds-steel-100); padding: .7rem 1.15rem;
  display: flex; align-items: center; justify-content: space-between; gap: .5rem;
  background: var(--ds-bg-soft);
}

/* Product card */
.product-card .spec-row {
  display: flex; flex-wrap: wrap; gap: .35rem .8rem; font-size: .78rem; color: var(--ds-muted);
  margin-top: .55rem; padding-top: .55rem; border-top: 1px dashed var(--ds-border);
}
.product-card .spec-row b { color: var(--ds-text); font-weight: 600; }

/* Person card */
.person-card h3 { font-size: .98rem; font-family: var(--ds-font-body); font-weight: 700; margin: .55rem 0 .15rem; }

/* Category tile */
/* ---------- category cards -------------------------------------------- */
.cat-grid { display: grid; gap: 1rem; grid-template-columns: repeat(2, minmax(0, 1fr)); }
@media (min-width: 768px)  { .cat-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
@media (min-width: 1100px) { .cat-grid { grid-template-columns: repeat(4, minmax(0, 1fr)); } }
@media (max-width: 575px)  { .cat-grid { gap: .7rem; } }
.cat-grid > * { min-width: 0; }

.cat-card {
  position: relative; display: block; overflow: hidden; height: 100%;
  min-height: 205px; border-radius: var(--ds-radius);
  background: var(--ds-navy-800); color: #fff; isolation: isolate;
  box-shadow: var(--ds-shadow-xs);
  transition: transform .4s var(--ds-ease), box-shadow .4s var(--ds-ease);
}
.cat-card--wide { min-height: 235px; }
.cat-card:hover { transform: translateY(-6px); box-shadow: var(--ds-shadow); color: #fff; }

.cat-media { position: absolute; inset: 0; z-index: 0; display: block; }
.cat-media img, .cat-media-fallback {
  width: 100%; height: 100%; object-fit: cover; display: block;
  transition: transform .8s var(--ds-ease), filter .5s var(--ds-ease);
  filter: saturate(.85);
}
.cat-card:hover .cat-media img { transform: scale(1.08); filter: saturate(1.05); }

.cat-overlay {
  position: absolute; inset: 0; z-index: 1; display: block;
  background: linear-gradient(180deg, rgba(5,13,28,.18) 0%, rgba(5,13,28,.55) 48%, rgba(5,13,28,.9) 100%);
  transition: background .4s var(--ds-ease);
}
.cat-card:hover .cat-overlay {
  background: linear-gradient(180deg, rgba(11,63,168,.28) 0%, rgba(5,13,28,.6) 46%, rgba(5,13,28,.93) 100%);
}

.cat-body {
  position: relative; z-index: 2; display: flex; flex-direction: column;
  height: 100%; justify-content: flex-end; padding: 1.05rem 1.05rem 1.15rem;
}
.cat-icon {
  width: 42px; height: 42px; border-radius: 12px; display: grid; place-items: center;
  font-size: 1.15rem; color: #fff; margin-bottom: auto;
  box-shadow: 0 6px 18px rgba(5,13,28,.4);
  transition: transform .45s var(--ds-ease);
}
.cat-card:hover .cat-icon { transform: translateY(-3px) rotate(-8deg) scale(1.06); }

.cat-name {
  display: block; font-family: var(--ds-font-display); font-weight: 700;
  font-size: 1.18rem; line-height: 1.15; letter-spacing: .01em; color: #fff;
  text-wrap: balance; margin-top: .8rem; overflow-wrap: anywhere;
}
.cat-count {
  display: block; font-size: .78rem; font-weight: 600; letter-spacing: .04em;
  text-transform: uppercase; color: var(--ds-gold-300); margin-top: .3rem;
}
.cat-desc {
  display: block; font-size: .82rem; line-height: 1.5; color: rgba(255,255,255,.72);
  margin-top: .45rem;
}

.cat-go {
  position: absolute; z-index: 3; right: .9rem; bottom: 1.05rem;
  width: 34px; height: 34px; border-radius: 50%; display: grid; place-items: center;
  background: var(--ds-accent); color: var(--ds-navy-900); font-size: .9rem;
  opacity: 0; transform: translateX(-8px) scale(.8);
  transition: opacity .3s var(--ds-ease), transform .35s var(--ds-ease);
}
.cat-card:hover .cat-go { opacity: 1; transform: none; }

/* gold rule that draws in along the bottom edge */
.cat-card::after {
  content: ''; position: absolute; z-index: 3; inset: auto 0 0 0; height: 3px;
  background: var(--ds-grad-gold); transform: scaleX(0); transform-origin: left;
  transition: transform .45s var(--ds-ease);
}
.cat-card:hover::after { transform: scaleX(1); }

@media (prefers-reduced-motion: reduce) {
  .cat-card, .cat-card *, .cat-card::after { transition: none !important; }
  .cat-card:hover { transform: none; }
}

/* Post card */
.post-card .img-wrap { aspect-ratio: 16 / 9; overflow: hidden; background: var(--ds-steel-100); }
.post-card .img-wrap img { width: 100%; height: 100%; object-fit: cover; transition: transform .5s var(--ds-ease); }
.ds-card:hover .post-card .img-wrap img, .post-card:hover .img-wrap img { transform: scale(1.06); }
.post-card h3 { font-size: 1.02rem; font-family: var(--ds-font-body); font-weight: 700; line-height: 1.4; margin: .5rem 0 .35rem; }
.post-card .post-meta { font-size: .78rem; color: var(--ds-muted); display: flex; gap: .8rem; flex-wrap: wrap; }

/* Event card */
.event-card { display: flex; gap: 0; }
.event-card .date-block {
  flex: none; width: 88px; background: var(--ds-grad-hero); color: #fff;
  display: grid; place-content: center; text-align: center; padding: 1rem .5rem;
}
.event-card .date-block .day { font-family: var(--ds-font-display); font-size: 1.9rem; font-weight: 800; line-height: 1; }
.event-card .date-block .mon { font-size: .76rem; text-transform: uppercase; letter-spacing: .1em; opacity: .8; }
.event-card .date-block .yr { font-size: .7rem; opacity: .6; }

/* Rating */
.rating-stars { color: var(--ds-gold-500); font-size: .82rem; letter-spacing: .5px; }
.rating-count { font-size: .76rem; color: var(--ds-muted); }

/* ---------- listing layout -------------------------------------------- */
.listing-wrap { display: grid; grid-template-columns: 282px 1fr; gap: 1.6rem; align-items: start; }
/* the sidebar column must span the full row height or the sticky panel
   inside it has nowhere to travel */
.listing-wrap > aside { align-self: stretch; min-width: 0; }
@media (max-width: 991px) { .listing-wrap { grid-template-columns: 1fr; } }

.filter-panel {
  background: #fff; border: 1px solid var(--ds-border); border-radius: var(--ds-radius);
  position: sticky; top: calc(var(--ds-header-h) + 12px); max-height: calc(100vh - var(--ds-header-h) - 28px);
  overflow-y: auto; overscroll-behavior: contain; scrollbar-gutter: stable;
  scrollbar-width: thin; scrollbar-color: var(--ds-steel-300) transparent;
  box-shadow: var(--ds-shadow-xs);
}
.filter-panel .filter-head {
  display: flex; align-items: center; justify-content: space-between;
  padding: .9rem 1rem; border-bottom: 1px solid var(--ds-border); position: sticky; top: 0; background: #fff; z-index: 2;
}
.filter-panel .filter-head h4 { font-size: .95rem; margin: 0; font-family: var(--ds-font-body); font-weight: 700; }
.filter-group { border-bottom: 1px solid var(--ds-steel-100); padding: .85rem 1rem; }
.filter-group:last-child { border-bottom: none; }
.filter-group > h5 {
  font-size: .78rem; font-weight: 700; text-transform: uppercase; letter-spacing: .07em;
  color: var(--ds-steel-700); margin: 0 0 .6rem; font-family: var(--ds-font-body);
  display: flex; align-items: center; justify-content: space-between; cursor: pointer;
}
.filter-group > h5 i { transition: transform .25s var(--ds-ease); font-size: .9rem; }
.filter-group.collapsed > h5 i { transform: rotate(-90deg); }
.filter-group.collapsed .filter-body { display: none; }
/* scrollbar-gutter reserves the track, so the scrollbar never sits on top
   of the count at the right edge of each option. */
.filter-body { max-height: 232px; overflow-y: auto; scrollbar-gutter: stable; padding-right: .3rem; }
.filter-body::-webkit-scrollbar, .filter-panel::-webkit-scrollbar { width: 8px; }
.filter-body::-webkit-scrollbar-thumb, .filter-panel::-webkit-scrollbar-thumb {
  background: var(--ds-steel-300); border-radius: 99px;
  border: 2px solid #fff; background-clip: padding-box;
}
.filter-body::-webkit-scrollbar-thumb:hover, .filter-panel::-webkit-scrollbar-thumb:hover { background: var(--ds-steel-500); background-clip: padding-box; }
.filter-body::-webkit-scrollbar-track, .filter-panel::-webkit-scrollbar-track { background: transparent; }
.filter-body { scrollbar-width: thin; scrollbar-color: var(--ds-steel-300) transparent; }
.filter-check {
  display: flex; align-items: center; gap: .5rem; padding: .22rem 0; font-size: .86rem; cursor: pointer;
  color: var(--ds-text);
}
.filter-check input { accent-color: var(--ds-primary); width: 15px; height: 15px; flex: none; }
.filter-check span.label { flex: 1; }
.filter-check .n { font-size: .74rem; color: var(--ds-steel-500); flex: none; padding-left: .25rem; font-variant-numeric: tabular-nums; }
.filter-check:hover { color: var(--ds-primary); }
.filter-more { font-size: .8rem; font-weight: 600; margin-top: .35rem; display: inline-block; }

.listing-toolbar {
  display: flex; align-items: center; justify-content: space-between; gap: 1rem; flex-wrap: wrap;
  background: #fff; border: 1px solid var(--ds-border); border-radius: var(--ds-radius);
  padding: .7rem .95rem; margin-bottom: 1.1rem;
}
.listing-toolbar .count { font-size: .88rem; color: var(--ds-muted); }
.listing-toolbar .count b { color: var(--ds-text); }
.listing-toolbar select {
  border: 1px solid var(--ds-border); border-radius: 8px; padding: .38rem .6rem;
  font-size: .86rem; font-weight: 600; color: var(--ds-text); background: #fff;
}
.view-toggle { display: inline-flex; gap: .25rem; }

.active-filters { display: flex; flex-wrap: wrap; gap: .4rem; margin-bottom: 1rem; }
.active-filters .chip { background: var(--ds-blue-050); border-color: var(--ds-blue-100); color: var(--ds-primary); }
.active-filters .chip i { font-size: .8rem; }

/* list view variant */
.view-list .ds-card { display: flex; }
@media (max-width: 575px) {
  .view-list .ds-card { display: block; }
}

/* ---------- profile / detail ------------------------------------------ */
.profile-hero {
  position: relative; color: #fff; overflow: hidden;
  padding: 2.6rem 0 2.2rem;
  background: var(--ds-grad-hero);
}
.profile-hero .cover {
  position: absolute; inset: 0; object-fit: cover; width: 100%; height: 100%; opacity: .25;
}
.profile-hero::after {
  content: ''; position: absolute; inset: 0;
  background: linear-gradient(90deg, rgba(5,13,28,.92), rgba(5,13,28,.55));
}
.profile-hero > .container-ds, .profile-hero > .container { position: relative; z-index: 2; }

.profile-identity { display: flex; gap: 1.4rem; align-items: flex-start; flex-wrap: wrap; }
.profile-logo {
  width: 138px; height: 138px; flex: none; background: #fff; border-radius: var(--ds-radius);
  display: grid; place-items: center; padding: 1rem; box-shadow: var(--ds-shadow-lg);
}
.profile-logo img { max-width: 100%; max-height: 100%; object-fit: contain; }
.profile-identity h1 { font-size: clamp(1.7rem, 3.2vw, 2.5rem); color: #fff; margin-bottom: .35rem; }
.profile-identity .sub { color: rgba(255,255,255,.78); font-size: .95rem; }
.profile-identity .quick-meta { display: flex; flex-wrap: wrap; gap: .5rem; margin-top: .7rem; }
.profile-identity .quick-meta .chip {
  background: rgba(255,255,255,.1); border-color: rgba(255,255,255,.2); color: rgba(255,255,255,.9);
}

.profile-tabs {
  background: #fff; border-bottom: 1px solid var(--ds-border);
  position: sticky; top: var(--ds-header-h); z-index: 1020;
  box-shadow: 0 2px 10px rgba(15,23,42,.04);
}
.profile-tabs .nav { flex-wrap: nowrap; overflow-x: auto; scrollbar-width: none; }
.profile-tabs .nav::-webkit-scrollbar { display: none; }
.profile-tabs .nav-link {
  border: none; border-bottom: 3px solid transparent; border-radius: 0;
  font-weight: 600; font-size: .92rem; color: var(--ds-muted); padding: .9rem 1.05rem; white-space: nowrap;
  transition: all .25s var(--ds-ease);
}
.profile-tabs .nav-link:hover { color: var(--ds-primary); }
.profile-tabs .nav-link.active { color: var(--ds-primary); border-bottom-color: var(--ds-primary); background: transparent; }

.info-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(210px, 1fr)); gap: .9rem; }
.info-tile {
  background: #fff; border: 1px solid var(--ds-border); border-radius: var(--ds-radius);
  padding: 1rem; display: flex; gap: .8rem; align-items: flex-start;
  transition: transform .3s var(--ds-ease), box-shadow .3s var(--ds-ease);
}
.info-tile:hover { transform: translateY(-3px); box-shadow: var(--ds-shadow-sm); }
.info-tile .icon {
  width: 40px; height: 40px; flex: none; border-radius: 11px; display: grid; place-items: center;
  background: var(--ds-blue-050); color: var(--ds-primary); font-size: 1.05rem;
}
.info-tile .label { font-size: .74rem; text-transform: uppercase; letter-spacing: .06em; color: var(--ds-steel-500); font-weight: 700; }
.info-tile .value { font-weight: 700; color: var(--ds-navy-800); font-size: .97rem; line-height: 1.35; }
/* Email addresses and URLs are single unbreakable tokens — let them wrap
   rather than push the tile past the edge of the grid. */
.info-tile { min-width: 0; }
.info-tile .value, .info-tile .label, .info-tile .muted, .info-tile a { overflow-wrap: anywhere; min-width: 0; }

.panel {
  background: #fff; border: 1px solid var(--ds-border); border-radius: var(--ds-radius);
  overflow: hidden; margin-bottom: 1.3rem;
}
.panel > .panel-head {
  padding: .95rem 1.15rem; border-bottom: 1px solid var(--ds-border);
  display: flex; align-items: center; justify-content: space-between; gap: .6rem;
  background: linear-gradient(180deg, #fff, var(--ds-bg-soft));
}
.panel > .panel-head h2, .panel > .panel-head h3 {
  font-size: 1.06rem; margin: 0; font-family: var(--ds-font-body); font-weight: 700;
  display: flex; align-items: center; gap: .55rem;
}
.panel > .panel-head h2 i, .panel > .panel-head h3 i { color: var(--ds-primary); }
.panel > .panel-body { padding: 1.15rem; }

.kv-table { width: 100%; font-size: .92rem; }
.kv-table tr { border-bottom: 1px solid var(--ds-steel-100); }
.kv-table tr:last-child { border-bottom: none; }
.kv-table td { padding: .6rem .2rem; vertical-align: top; }
.kv-table td:first-child { color: var(--ds-muted); width: 42%; }
.kv-table td:last-child { font-weight: 600; color: var(--ds-navy-800); }

.feature-list { list-style: none; padding: 0; margin: 0; }
.feature-list li {
  position: relative; padding-left: 1.7rem; margin-bottom: .55rem; font-size: .93rem;
}
.feature-list li::before {
  content: '\F26E'; font-family: 'bootstrap-icons'; position: absolute; left: 0; top: .05rem;
  color: var(--ds-success); font-size: .95rem;
}

/* Timeline */
.ds-timeline { position: relative; padding-left: 2rem; }
.ds-timeline::before {
  content: ''; position: absolute; left: 7px; top: .4rem; bottom: .4rem; width: 2px;
  background: linear-gradient(to bottom, var(--ds-blue-400), var(--ds-steel-300));
}
.ds-timeline .tl-item { position: relative; padding-bottom: 1.35rem; }
.ds-timeline .tl-item::before {
  content: ''; position: absolute; left: -1.68rem; top: .38rem; width: 14px; height: 14px;
  border-radius: 50%; background: #fff; border: 3px solid var(--ds-primary);
  box-shadow: 0 0 0 3px var(--ds-blue-050);
}
.ds-timeline .tl-year {
  font-family: var(--ds-font-display); font-weight: 700; color: var(--ds-primary); font-size: 1.02rem;
}
.ds-timeline .tl-title { font-weight: 700; color: var(--ds-navy-800); }
.ds-timeline .tl-desc { font-size: .9rem; color: var(--ds-muted); }

/* Gallery */
.ds-gallery { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: .6rem; }
.ds-gallery a {
  display: block; aspect-ratio: 4/3; overflow: hidden; border-radius: 10px; position: relative;
  background: var(--ds-steel-100);
}
.ds-gallery img { width: 100%; height: 100%; object-fit: cover; transition: transform .45s var(--ds-ease); }
.ds-gallery a:hover img { transform: scale(1.08); }
.ds-gallery a::after {
  content: '\F4FE'; font-family: 'bootstrap-icons'; position: absolute; inset: 0;
  display: grid; place-items: center; color: #fff; font-size: 1.4rem;
  background: rgba(5,13,28,.4); opacity: 0; transition: opacity .3s var(--ds-ease);
}
.ds-gallery a:hover::after { opacity: 1; }

/* Sticky sidebar */
.sticky-side { position: sticky; top: calc(var(--ds-header-h) + 62px); }

/* ---------- comparison ------------------------------------------------- */
.compare-table-wrap { overflow-x: auto; border: 1px solid var(--ds-border); border-radius: var(--ds-radius); background: #fff; }
.compare-table { width: 100%; border-collapse: separate; border-spacing: 0; min-width: 760px; }
.compare-table th, .compare-table td {
  padding: .85rem 1rem; border-bottom: 1px solid var(--ds-steel-100); vertical-align: middle; font-size: .92rem;
}
/* `top` is measured against the nearest scrolling ancestor, and
   .compare-table-wrap is one because of its overflow-x. So top:var(--ds-header-h)
   did not park the header under the site header — it shoved every header cell
   120px down inside the wrapper, permanently, straight over the first two rows.
   That is the "Category row is cropped" bug. The wrapper never scrolls
   vertically, so the offset has to be zero. */
.compare-table thead th {
  position: sticky; top: 0; background: #fff; z-index: 5;
  border-bottom: 2px solid var(--ds-border); text-align: center; vertical-align: top; padding: 1rem;
}
.compare-table tbody th {
  text-align: left; font-weight: 600; color: var(--ds-muted); width: 200px;
  background: var(--ds-bg-soft); position: sticky; left: 0; z-index: 2;
}
.compare-table td { text-align: center; }
.compare-table .group-row th {
  background: var(--ds-navy-800); color: #fff; font-family: var(--ds-font-display);
  font-size: .95rem; letter-spacing: .04em; text-transform: uppercase; padding: .6rem 1rem;
}
.compare-table .row-same td, .compare-table .row-same th { opacity: .68; }
.compare-table td.winner {
  background: #ecfdf5; font-weight: 700; color: var(--ds-success); position: relative;
}
.compare-table td.winner::after {
  content: '\F26B'; font-family: 'bootstrap-icons'; margin-left: .35rem; font-size: .85rem;
}
.compare-head-card { text-align: center; min-width: 190px; position: relative; }
/* Column widths live here rather than in inline styles, so the mobile rules
   further down can actually override them. */
.compare-label-head { min-width: 190px; text-align: left; }
.compare-slot-head  { min-width: 190px; }
.compare-head-card img { height: 74px; object-fit: contain; margin-bottom: .5rem; }
.compare-head-card .name { font-weight: 700; font-size: .95rem; line-height: 1.3; color: var(--ds-navy-800); }
.compare-head-card .brand { font-size: .78rem; color: var(--ds-muted); }
.compare-head-card .remove {
  position: absolute; top: .4rem; right: .4rem; width: 24px; height: 24px; border-radius: 50%;
  background: var(--ds-steel-100); color: var(--ds-steel-700); display: grid; place-items: center;
  font-size: .72rem; border: none;
}
.compare-head-card .remove:hover { background: var(--ds-danger); color: #fff; }

.compare-slot {
  border: 2px dashed var(--ds-steel-300); border-radius: var(--ds-radius);
  min-height: 150px; display: grid; place-items: center; text-align: center;
  color: var(--ds-steel-500); padding: 1rem; transition: all .3s var(--ds-ease); cursor: pointer;
}
.compare-slot:hover { border-color: var(--ds-primary); color: var(--ds-primary); background: var(--ds-blue-050); }

/* floating compare tray */
.compare-tray {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 1050;
  background: #fff; border-top: 1px solid var(--ds-border);
  box-shadow: 0 -12px 40px rgba(15,23,42,.14);
  transform: translateY(110%); transition: transform .4s var(--ds-ease-out);
  padding: .8rem 0;
}
.compare-tray.open { transform: none; }
.compare-tray .tray-inner { display: flex; align-items: center; gap: 1rem; flex-wrap: wrap; }
.compare-tray .tray-items { display: flex; gap: .6rem; flex: 1; flex-wrap: wrap; }
.compare-tray .tray-item {
  display: flex; align-items: center; gap: .5rem; background: var(--ds-bg-soft);
  border: 1px solid var(--ds-border); border-radius: 10px; padding: .35rem .55rem; font-size: .84rem;
  max-width: 220px;
}
.compare-tray .tray-item img { width: 30px; height: 30px; object-fit: contain; }
.compare-tray .tray-item .name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-weight: 600; }
.compare-tray .tray-item button { border: none; background: none; color: var(--ds-steel-500); font-size: .8rem; }
.compare-tray .tray-item button:hover { color: var(--ds-danger); }

/* ---------- top lists --------------------------------------------------- */
.rank-item {
  display: flex; gap: 1.1rem; align-items: flex-start; padding: 1.15rem;
  background: #fff; border: 1px solid var(--ds-border); border-radius: var(--ds-radius);
  margin-bottom: .9rem; position: relative; overflow: hidden;
  transition: transform .3s var(--ds-ease), box-shadow .3s var(--ds-ease);
}
.rank-item:hover { transform: translateX(4px); box-shadow: var(--ds-shadow); }
.rank-item .rank-no {
  flex: none; width: 52px; height: 52px; border-radius: 14px; display: grid; place-items: center;
  font-family: var(--ds-font-display); font-size: 1.5rem; font-weight: 800; color: #fff;
  background: var(--ds-grad-blue); box-shadow: 0 6px 16px rgba(11,87,208,.28);
}
.rank-item:nth-child(1) .rank-no { background: var(--ds-grad-gold); color: var(--ds-navy-900); box-shadow: 0 6px 16px rgba(245,179,1,.35); }
.rank-item:nth-child(2) .rank-no { background: var(--ds-grad-steel); color: var(--ds-navy-800); }
.rank-item:nth-child(3) .rank-no { background: linear-gradient(135deg, #b45309, #f59e0b); }
.rank-item .thumb {
  width: 76px; height: 76px; flex: none; border-radius: 12px; object-fit: contain;
  background: var(--ds-steel-100); padding: .4rem;
}
.rank-item h3 { font-size: 1.08rem; font-family: var(--ds-font-body); font-weight: 700; margin: 0 0 .25rem; }

/* ---------- forms ------------------------------------------------------- */
.form-label { font-weight: 600; font-size: .87rem; color: var(--ds-text); margin-bottom: .35rem; }
.form-control, .form-select {
  border: 1px solid var(--ds-border); border-radius: var(--ds-radius-sm);
  padding: .62rem .85rem; font-size: .93rem; transition: all .22s var(--ds-ease);
}
.form-control:focus, .form-select:focus {
  border-color: var(--ds-blue-400); box-shadow: var(--ds-shadow-glow);
}
.form-control::placeholder { color: var(--ds-steel-500); }
.form-check-input:checked { background-color: var(--ds-primary); border-color: var(--ds-primary); }
.hp-field { position: absolute !important; left: -9999px !important; opacity: 0 !important; height: 0 !important; }

.ds-alert {
  border: none; border-left: 4px solid; border-radius: var(--ds-radius-sm);
  padding: .85rem 1.1rem; font-size: .92rem; display: flex; align-items: flex-start; gap: .65rem;
  animation: dsSlideIn .4s var(--ds-ease-out);
}
.ds-alert.alert-success { background: #ecfdf5; border-color: var(--ds-success); color: #065f46; }
.ds-alert.alert-danger  { background: #fef2f2; border-color: var(--ds-danger); color: #991b1b; }
.ds-alert.alert-warning { background: #fffbeb; border-color: var(--ds-warning); color: #92400e; }
.ds-alert.alert-info    { background: #f0f9ff; border-color: var(--ds-info); color: #075985; }
@keyframes dsSlideIn { from { opacity: 0; transform: translateY(-10px); } to { opacity: 1; transform: none; } }

/* ---------- pagination --------------------------------------------------- */
.ds-pagination { gap: .3rem; justify-content: center; margin-top: 2rem; }
.ds-pagination .page-link {
  border: 1px solid var(--ds-border); border-radius: 10px; color: var(--ds-text);
  min-width: 40px; text-align: center; font-weight: 600; font-size: .88rem; padding: .5rem .7rem;
  transition: all .22s var(--ds-ease);
}
.ds-pagination .page-link:hover { background: var(--ds-blue-050); border-color: var(--ds-blue-400); color: var(--ds-primary); }
.ds-pagination .page-item.active .page-link {
  background: var(--ds-grad-blue); border-color: transparent; color: #fff;
  box-shadow: 0 4px 12px rgba(11,87,208,.3);
}
.ds-pagination .page-item.disabled .page-link { opacity: .45; }

/* ---------- footer (two sections) ------------------------------------- */
.ds-footer {
  background: var(--ds-navy-900); color: rgba(255,255,255,.66);
  padding-top: 3.2rem; position: relative; font-size: .92rem;
}
.ds-footer::before {
  content: ''; position: absolute; top: 0; left: 0; right: 0; height: 3px; background: var(--ds-grad-blue);
}
.ds-footer a { color: rgba(255,255,255,.66); transition: color .2s var(--ds-ease); }
.ds-footer a:hover { color: #fff; }
.ds-footer h5 {
  color: #fff; font-size: .78rem; text-transform: uppercase; letter-spacing: .12em;
  font-family: var(--ds-font-body); font-weight: 800; margin: 0 0 1.1rem;
}
.ds-footer ul { list-style: none; padding: 0; margin: 0; }

/* --- SECTION 1: brand block + three link columns, one grid ------------- */
.foot-main {
  display: grid;
  grid-template-columns: minmax(0, 1.6fr) repeat(3, minmax(0, 1fr));
  gap: clamp(1.6rem, 4vw, 3.2rem);
  align-items: start;
  padding-bottom: 2.4rem;
}
@media (max-width: 1099px) { .foot-main { grid-template-columns: repeat(3, minmax(0, 1fr)); }
                             .foot-brand { grid-column: 1 / -1; } }
@media (max-width: 700px)  { .foot-main { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 1.6rem; } }
@media (max-width: 420px)  { .foot-main { grid-template-columns: 1fr; } }

.foot-logo { display: inline-flex; align-items: center; gap: .6rem; margin-bottom: 1rem; }
.foot-logo img { height: 46px; width: auto; }
.foot-logo .wordmark {
  font-family: var(--ds-font-display); font-weight: 800; font-size: 1.32rem; line-height: .95;
  text-transform: uppercase; color: #fff;
}
.foot-logo .wordmark span { display: block; color: var(--ds-blue-400); }

.foot-tagline { max-width: 44ch; margin: 0 0 1.2rem; line-height: 1.65; }

.ds-footer ul.foot-contact { display: grid; gap: .55rem; margin: 0 0 1.6rem; }
.foot-contact li { display: grid; grid-template-columns: 20px 1fr; gap: .5rem; align-items: start; }
.foot-contact i { color: var(--ds-blue-400); font-size: .95rem; line-height: 1.6; }
.foot-contact span, .foot-contact a { line-height: 1.6; }

.foot-news { max-width: 420px; margin-bottom: 1.3rem; }
.foot-news label {
  display: block; font-size: .78rem; font-weight: 700; letter-spacing: .06em;
  text-transform: uppercase; color: rgba(255,255,255,.55); margin-bottom: .55rem;
}
.foot-news .form-control {
  background: rgba(255,255,255,.08); border-color: rgba(255,255,255,.18); color: #fff; font-size: .9rem;
}
.foot-news .form-control::placeholder { color: rgba(255,255,255,.45); }
.foot-news .form-control:focus {
  background: rgba(255,255,255,.14); border-color: var(--ds-blue-400); box-shadow: none; color: #fff;
}

.foot-links { display: flex; gap: .5rem; flex-wrap: wrap; }
.foot-links a {
  width: 38px; height: 38px; border-radius: 10px; display: grid; place-items: center;
  background: rgba(255,255,255,.07); color: rgba(255,255,255,.8);
  transition: all .28s var(--ds-ease);
}
.foot-links a:hover { background: var(--ds-primary); color: #fff; transform: translateY(-3px); }

.foot-col ul { display: grid; gap: .55rem; align-content: start; }
.foot-col li { line-height: 1.5; }
.foot-col a { display: inline-block; position: relative; }
.foot-col a::after {
  content: ''; position: absolute; left: 0; right: 0; bottom: -2px; height: 1px;
  background: currentColor; transform: scaleX(0); transform-origin: right;
  transition: transform .3s var(--ds-ease);
}
.foot-col a:hover::after { transform: scaleX(1); transform-origin: left; }

/* --- SECTION 2: copyright and legal links ----------------------------- */
.foot-bottom {
  border-top: 1px solid rgba(255,255,255,.09);
  padding: 1.15rem 0 1.3rem; font-size: .82rem;
  display: flex; align-items: center; justify-content: space-between;
  gap: .8rem 1.6rem; flex-wrap: wrap;
}
.foot-copy { margin: 0; }
.foot-legal { display: flex; gap: 1.3rem; flex-wrap: wrap; }
/* Below desktop the bottom row stacks and centres, with room left for the
   floating back-to-top button so it never sits on top of a link. */
@media (max-width: 991px) {
  .foot-bottom { justify-content: center; text-align: center; padding-bottom: 3.6rem; }
  .foot-copy, .foot-legal { width: 100%; }
  .foot-legal { justify-content: center; }
}

/* ---------- CTA strip ------------------------------------------------------ */
.cta-strip {
  background: var(--ds-grad-hero); color: #fff; border-radius: var(--ds-radius-lg);
  padding: clamp(2rem, 4vw, 3rem); position: relative; overflow: hidden;
}
.cta-strip::after {
  content: ''; position: absolute; right: -60px; top: -60px; width: 260px; height: 260px;
  border-radius: 50%; background: radial-gradient(circle, rgba(245,179,1,.24), transparent 68%);
  animation: dsPulse 6s ease-in-out infinite;
}
@keyframes dsPulse { 0%,100% { transform: scale(1); opacity: .9; } 50% { transform: scale(1.16); opacity: .6; } }
.cta-strip h2 { color: #fff; }

/* ---------- marquee ---------------------------------------------------------- */
.logo-marquee { overflow: hidden; position: relative; padding: 1.2rem 0; }
.logo-marquee::before, .logo-marquee::after {
  content: ''; position: absolute; top: 0; bottom: 0; width: 90px; z-index: 2;
}
.logo-marquee::before { left: 0; background: linear-gradient(90deg, var(--ds-bg-soft), transparent); }
.logo-marquee::after { right: 0; background: linear-gradient(-90deg, var(--ds-bg-soft), transparent); }
.logo-marquee .track { display: flex; gap: 3rem; width: max-content; animation: dsMarquee 38s linear infinite; }
.logo-marquee:hover .track { animation-play-state: paused; }
.logo-marquee img { height: 40px; object-fit: contain; filter: grayscale(1); opacity: .58; transition: all .3s var(--ds-ease); }
.logo-marquee img:hover { filter: none; opacity: 1; transform: scale(1.06); }
@keyframes dsMarquee { from { transform: translateX(0); } to { transform: translateX(-50%); } }

/* ---------- animations ------------------------------------------------------- */
/* Scroll reveals are an ENHANCEMENT, never a prerequisite for seeing the page.
   Nothing is hidden unless JavaScript has confirmed it can run the animation
   (html.js-reveal), and html.reveal-off is the escape hatch that puts
   everything back if the script fails, stalls or is blocked. */
.js-reveal:not(.reveal-off) [data-reveal] {
  opacity: 0; transform: translateY(26px);
  transition: opacity .7s var(--ds-ease-out), transform .7s var(--ds-ease-out);
}
.js-reveal:not(.reveal-off) [data-reveal="left"]  { transform: translateX(-30px); }
.js-reveal:not(.reveal-off) [data-reveal="right"] { transform: translateX(30px); }
/* On narrow screens a sideways start position pushes full-width blocks past
   the edge and produces a horizontal scrollbar, so slide them up instead. */
@media (max-width: 991px) {
  .js-reveal:not(.reveal-off) [data-reveal="left"],
  .js-reveal:not(.reveal-off) [data-reveal="right"] { transform: translateY(24px); }
}
.js-reveal:not(.reveal-off) [data-reveal="zoom"]  { transform: scale(.94); }
.js-reveal:not(.reveal-off) [data-reveal].revealed { opacity: 1; transform: none; }
.reveal-off [data-reveal] { opacity: 1 !important; transform: none !important; transition: none !important; }
[data-reveal-delay="1"] { transition-delay: .08s; }
[data-reveal-delay="2"] { transition-delay: .16s; }
[data-reveal-delay="3"] { transition-delay: .24s; }
[data-reveal-delay="4"] { transition-delay: .32s; }
[data-reveal-delay="5"] { transition-delay: .40s; }
[data-reveal-delay="6"] { transition-delay: .48s; }

.float-slow { animation: dsFloat 7s ease-in-out infinite; }
@keyframes dsFloat { 0%,100% { transform: translateY(0); } 50% { transform: translateY(-12px); } }

.shimmer {
  background: linear-gradient(100deg, var(--ds-steel-100) 20%, #fff 40%, var(--ds-steel-100) 60%);
  background-size: 220% 100%; animation: dsShimmer 1.5s linear infinite;
}
@keyframes dsShimmer { from { background-position: 200% 0; } to { background-position: -20% 0; } }

.spin-slow { animation: dsSpin 18s linear infinite; }
@keyframes dsSpin { to { transform: rotate(360deg); } }

.hover-lift { transition: transform .3s var(--ds-ease), box-shadow .3s var(--ds-ease); }
.hover-lift:hover { transform: translateY(-5px); box-shadow: var(--ds-shadow); }

/* back to top */
.back-to-top {
  position: fixed; right: 20px; bottom: 20px; width: 46px; height: 46px; border-radius: 50%;
  background: var(--ds-grad-blue); color: #fff; border: none; display: grid; place-items: center;
  box-shadow: 0 8px 24px rgba(11,87,208,.36); z-index: 1040;
  opacity: 0; visibility: hidden; transform: translateY(14px);
  transition: all .35s var(--ds-ease);
}
.back-to-top.show { opacity: 1; visibility: visible; transform: none; }
.back-to-top:hover { transform: translateY(-3px); }

/* progress bar for article reading */
.read-progress {
  position: fixed; top: 0; left: 0; height: 3px; background: var(--ds-grad-gold); z-index: 1060; width: 0;
  transition: width .1s linear;
}

/* Empty state */
.empty-state { text-align: center; padding: 3.5rem 1rem; color: var(--ds-muted); }
.empty-state i { font-size: 3.2rem; color: var(--ds-steel-300); display: block; margin-bottom: .8rem; }
.empty-state h3 { font-family: var(--ds-font-body); font-size: 1.15rem; color: var(--ds-text); }

/* prose */
.prose { font-size: 1rem; line-height: 1.8; color: #334155; }
.prose h2 { margin: 2rem 0 .8rem; font-size: 1.5rem; }
.prose h3 { margin: 1.6rem 0 .6rem; font-size: 1.22rem; }
.prose p { margin-bottom: 1.05rem; }
.prose ul, .prose ol { margin-bottom: 1.05rem; padding-left: 1.3rem; }
.prose li { margin-bottom: .4rem; }
.prose img { border-radius: var(--ds-radius); margin: 1.2rem 0; }
.prose blockquote {
  border-left: 4px solid var(--ds-primary); background: var(--ds-blue-050);
  padding: .9rem 1.2rem; border-radius: 0 10px 10px 0; margin: 1.2rem 0; font-style: italic;
}
.prose table { width: 100%; margin-bottom: 1.2rem; border: 1px solid var(--ds-border); border-radius: 10px; }
.prose th, .prose td { padding: .6rem .8rem; border-bottom: 1px solid var(--ds-steel-100); }
.prose th { background: var(--ds-bg-soft); text-align: left; font-weight: 700; }

/* accordion */
.ds-accordion .accordion-item { border: 1px solid var(--ds-border); border-radius: var(--ds-radius) !important; margin-bottom: .7rem; overflow: hidden; }
.ds-accordion .accordion-button { font-weight: 600; font-size: .98rem; padding: 1rem 1.15rem; }
.ds-accordion .accordion-button:not(.collapsed) { background: var(--ds-blue-050); color: var(--ds-primary); box-shadow: none; }
.ds-accordion .accordion-button:focus { box-shadow: none; border-color: transparent; }

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

/* mobile filter drawer */
@media (max-width: 991px) {
  .filter-panel {
    position: fixed; inset: 0 auto 0 0; width: min(88vw, 340px); max-height: 100vh;
    border-radius: 0; z-index: 1060; transform: translateX(-102%);
    transition: transform .35s var(--ds-ease-out); box-shadow: var(--ds-shadow-lg);
  }
  .filter-panel.open { transform: none; }
  .filter-backdrop {
    position: fixed; inset: 0; background: rgba(5,13,28,.5); z-index: 1055;
    opacity: 0; visibility: hidden; transition: all .3s var(--ds-ease);
  }
  .filter-backdrop.show { opacity: 1; visibility: visible; }
}
@media (min-width: 992px) { .filter-toggle-btn { display: none !important; } }


/* ---------- notification opt-in card ------------------------------------- */
.push-prompt {
  position: fixed; z-index: 1070; left: 1rem; bottom: 1rem; width: min(418px, calc(100vw - 2rem));
  display: flex; gap: .9rem; padding: 1.05rem 1.1rem;
  background: #fff; border: 1px solid var(--ds-border); border-radius: var(--ds-radius);
  box-shadow: 0 22px 55px rgba(10, 25, 48, .22);
  opacity: 0; transform: translateY(18px) scale(.97);
  transition: opacity .32s var(--ds-ease-out), transform .32s var(--ds-ease-out);
}
.push-prompt.is-open { opacity: 1; transform: none; }
.push-prompt::before {
  content: ''; position: absolute; inset: 0 0 auto 0; height: 3px;
  background: var(--ds-grad-blue); border-radius: var(--ds-radius) var(--ds-radius) 0 0;
}
.push-prompt-icon {
  width: 44px; height: 44px; flex: none; border-radius: 13px; display: grid; place-items: center;
  background: var(--ds-grad-blue); color: #fff; font-size: 1.2rem;
  box-shadow: 0 8px 20px rgba(11, 87, 208, .3);
}
.push-prompt-body { min-width: 0; }
.push-prompt h4 {
  font-family: var(--ds-font-body); font-size: 1rem; font-weight: 700;
  color: var(--ds-navy-800); margin: 0 0 .25rem;
}
.push-prompt p { font-size: .87rem; line-height: 1.5; color: var(--ds-muted); margin: 0 0 .85rem; }
.push-prompt-actions { display: flex; gap: .5rem; flex-wrap: wrap; }
.push-prompt-actions .btn { white-space: nowrap; }
.push-prompt-close {
  position: absolute; top: .5rem; right: .55rem; width: 28px; height: 28px;
  border: 0; background: none; color: var(--ds-steel-500); border-radius: 8px;
  display: grid; place-items: center; font-size: .8rem;
}
.push-prompt-close:hover { background: var(--ds-steel-100); color: var(--ds-text); }

@media (max-width: 575px) {
  .push-prompt { left: .6rem; right: .6rem; bottom: .6rem; width: auto; padding: .95rem; }
  .push-prompt-actions .btn { flex: 1; justify-content: center; }
}
@media (prefers-reduced-motion: reduce) {
  .push-prompt { transition: none; }
}

/* a "turn notifications on" button anywhere on the site */
.push-toggle { display: inline-flex; align-items: center; gap: .45rem; }

/* ---------- sponsored placement badge ------------------------------------
   Marks a slot someone has paid for. Deliberately quiet — it has to read as
   a disclosure, not as an award, so it must not outshine "Featured".        */
.partner-badge {
  position: absolute; top: .6rem; left: .6rem; z-index: 3;
  display: inline-flex; align-items: center; gap: .3rem;
  padding: .2rem .5rem; border-radius: 999px;
  background: rgba(15, 23, 42, .78); color: #fff;
  font-size: .66rem; font-weight: 700; letter-spacing: .04em; text-transform: uppercase;
  backdrop-filter: blur(4px);
  border: 1px solid rgba(255, 255, 255, .18);
}
.partner-badge i { font-size: .72em; }
.product-card .partner-badge { top: auto; bottom: .6rem; left: .6rem; }

/* Settings → Appearance → Sticky Header, switched off. */
body.header-static .site-header,
body.header-static .hdr-main,
body.header-static .hdr-bottom { position: static !important; top: auto !important; }
body.header-static { --ds-header-h: 0px; }

/* ---------- cover band + identity badge --------------------------------
   The LinkedIn/Facebook shape, used by both the listing cards and the detail
   page headers: a wide cover photo, the logo or avatar as a badge straddling
   its bottom edge, and every word of the record's detail BELOW the image.
   Printing the name and meta over the cover made both unreadable — the text
   fought the photograph for contrast and the photograph lost its subject.   */
.cv-band {
  position: relative; display: block; overflow: hidden;
  aspect-ratio: 16 / 5; min-height: 96px;
  background: var(--ds-grad-hero);
}
.cv-band .cv-img {
  width: 100%; height: 100%; object-fit: cover; display: block;
  transition: transform .7s var(--ds-ease);
}
.ds-card:hover .cv-band .cv-img { transform: scale(1.05); }
/* Records with no cover get a quiet patterned band rather than a blank grey
   box, so a card without artwork still has a header shape. */
.cv-band.is-empty::after {
  content: ''; position: absolute; inset: 0; opacity: .5;
  background:
    radial-gradient(circle at 18% 120%, rgba(11,87,208,.55), transparent 60%),
    repeating-linear-gradient(115deg, rgba(255,255,255,.05) 0 12px, transparent 12px 26px);
}

.cv-badge {
  position: relative; z-index: 2; flex: none;
  width: 66px; height: 66px; margin: -33px 0 0 1.05rem;
  border: none; border-radius: 15px; background: #fff; padding: .38rem;
  display: grid; place-items: center; overflow: hidden;
  box-shadow: 0 6px 18px rgba(5, 13, 28, .2);
}
.cv-badge img { max-width: 100%; max-height: 100%; object-fit: contain; border: none; }
/* Photographs fill their badge; logos are letterboxed inside it. */
.cv-badge.is-photo { padding: 0; border-radius: 50%; }
.cv-badge.is-photo img { width: 100%; height: 100%; object-fit: cover; }
.cv-badge.is-cover { padding: 0; }
.cv-badge.is-cover img { width: 100%; height: 100%; object-fit: cover; }

/* ---------- listing cards on the cover pattern -------------------------- */
.ds-card .cv-body { padding: .55rem 1.15rem 1.1rem; }
.ds-card .cv-body h3 {
  font-size: 1.02rem; font-family: var(--ds-font-body); font-weight: 700;
  margin: 0 0 .3rem; line-height: 1.35;
}
.ds-card .cv-body h3 a { color: var(--ds-navy-800); }
.ds-card .cv-body h3 a:hover { color: var(--ds-primary); }
.ds-card .cv-meta {
  font-size: .8rem; color: var(--ds-muted);
  display: flex; align-items: center; gap: .35rem; flex-wrap: wrap;
}
.ds-card .cv-desc { font-size: .85rem; line-height: 1.5; color: var(--ds-muted); margin: .45rem 0 0; }
.product-card .cv-band { aspect-ratio: 16 / 9; }
.person-card { text-align: left; }
.person-card .cv-badge { width: 76px; height: 76px; margin-top: -38px; }
.company-card .cv-band, .person-card .cv-band { aspect-ratio: 16 / 5; }

/* list view: the band becomes a side panel, details stay beside it */
.view-list .ds-card .cv-band { width: 220px; aspect-ratio: auto; align-self: stretch; flex: none; }
.view-list .ds-card .cv-badge { display: none; }
.view-list .ds-card .cv-body { padding-top: 1.1rem; }
@media (max-width: 575px) {
  .view-list .ds-card .cv-band { width: 100%; aspect-ratio: 16 / 5; }
  .view-list .ds-card .cv-badge { display: grid; }
  .view-list .ds-card .cv-body { padding-top: .55rem; }
}

/* ---------- detail page header ------------------------------------------ */
.profile-head { background: #fff; border-bottom: 1px solid var(--ds-border); }
.profile-head .ph-crumbs { padding: .7rem 0 .1rem; }
.profile-head .ph-crumbs .ds-breadcrumb .breadcrumb-item,
.profile-head .ph-crumbs .ds-breadcrumb a { color: var(--ds-muted); }
.profile-head .ph-crumbs .ds-breadcrumb a:hover { color: var(--ds-primary); }
.profile-head .ph-crumbs .ds-breadcrumb .breadcrumb-item.active { color: var(--ds-text); }
.profile-head .ph-crumbs .ds-breadcrumb .breadcrumb-item + .breadcrumb-item::before { color: var(--ds-steel-300); }

.ph-cover {
  position: relative; display: block; overflow: hidden;
  aspect-ratio: 4 / 1; max-height: 300px; min-height: 150px;
  border-radius: var(--ds-radius); background: var(--ds-grad-hero);
}
.ph-cover img { width: 100%; height: 100%; object-fit: cover; display: block; }
.ph-cover.is-empty::after {
  content: ''; position: absolute; inset: 0; opacity: .55;
  background:
    radial-gradient(circle at 12% 130%, rgba(11,87,208,.6), transparent 62%),
    repeating-linear-gradient(115deg, rgba(255,255,255,.05) 0 14px, transparent 14px 30px);
}
a.ph-cover:hover img { transform: none; }

.ph-body { display: flex; gap: 1.2rem; align-items: flex-start; padding-bottom: 1.5rem; }
.ph-badge {
  flex: none; width: 132px; height: 132px; margin: -46px 0 0;
  border: none; border-radius: 18px; background: #fff; padding: .7rem;
  display: grid; place-items: center; overflow: hidden;
  box-shadow: 0 10px 30px rgba(5, 13, 28, .22);
}
.ph-badge img { max-width: 100%; max-height: 100%; object-fit: contain; border: none; }
.ph-badge.is-photo { padding: 0; border-radius: 50%; }
.ph-badge.is-photo img { width: 100%; height: 100%; object-fit: cover; }

.ph-main { flex: 1 1 auto; min-width: 0; padding-top: .9rem; }
.ph-main h1 {
  font-size: clamp(1.5rem, 2.6vw, 2.1rem); color: var(--ds-navy-800); margin: 0 0 .3rem; line-height: 1.2;
}
.ph-main .ph-sub { color: var(--ds-muted); font-size: .97rem; margin: 0 0 .2rem; }
.ph-main .ph-sub a { font-weight: 600; }
.ph-meta { display: flex; flex-wrap: wrap; gap: .45rem; margin-top: .7rem; }
.ph-actions { display: flex; flex-wrap: wrap; gap: .5rem; margin-top: .9rem; }

@media (max-width: 767px) {
  .ph-cover { aspect-ratio: 3 / 1; min-height: 108px; border-radius: 12px; }
  .ph-body { flex-direction: column; gap: .5rem; padding-bottom: 1.15rem; }
  .ph-badge { width: 92px; height: 92px; margin-top: -34px; border-radius: 14px; }
  .ph-main { padding-top: 0; }
  .ph-main h1 { font-size: 1.35rem; }
  .ph-actions .btn { flex: 1 1 auto; justify-content: center; }
}

/* ---------- media gallery tiles ----------------------------------------- */
.ds-gallery a.gal-item { background: var(--ds-navy-800); }
/* The magnifier overlay reads as "zoom", which is wrong for a video tile —
   those already carry a play button, so hover just dims them. */
.ds-gallery a.gal-video::after, .ds-gallery a.gal-youtube::after { content: ''; }
.gal-play {
  position: absolute; inset: 0; z-index: 2; display: grid; place-items: center;
  color: #fff; font-size: 1.5rem; pointer-events: none;
}
.gal-play i {
  width: 46px; height: 46px; border-radius: 50%; display: grid; place-items: center;
  background: rgba(5, 13, 28, .62); backdrop-filter: blur(3px);
  transition: transform .3s var(--ds-ease), background .3s var(--ds-ease);
}
.ds-gallery a:hover .gal-play i { transform: scale(1.1); background: var(--ds-primary); }
.gal-caption {
  position: absolute; inset: auto 0 0 0; z-index: 3; padding: .8rem .6rem .45rem;
  background: linear-gradient(to top, rgba(5, 13, 28, .85), transparent);
  color: #fff; font-size: .76rem; line-height: 1.3;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

/* ---------- lightbox ----------------------------------------------------- */
.ds-lb {
  position: fixed; inset: 0; z-index: 1090; display: flex; flex-direction: column;
  align-items: center; justify-content: center; gap: .6rem;
  padding: clamp(.75rem, 4vw, 2.5rem); background: rgba(5, 13, 28, .95);
}
.ds-lb[hidden] { display: none; }
.ds-lb-stage {
  display: flex; align-items: center; justify-content: center;
  max-width: min(1100px, 100%); max-height: 78vh; width: 100%; min-height: 0;
}
.ds-lb-stage > img, .ds-lb-stage > video {
  max-width: 100%; max-height: 78vh; border-radius: 12px;
  box-shadow: 0 30px 80px rgba(0, 0, 0, .6); background: #000;
}
.ds-lb-frame {
  position: relative; width: 100%; max-width: 1000px; aspect-ratio: 16 / 9;
  border-radius: 12px; overflow: hidden; background: #000;
  box-shadow: 0 30px 80px rgba(0, 0, 0, .6);
}
.ds-lb-frame iframe { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; }
.ds-lb-cap {
  color: rgba(255, 255, 255, .88); font-size: .9rem; text-align: center;
  max-width: 60ch; margin: 0;
}
.ds-lb-count { color: rgba(255, 255, 255, .55); font-size: .78rem; letter-spacing: .06em; }
.ds-lb-close, .ds-lb-nav {
  position: absolute; border: none; color: #fff; background: rgba(255, 255, 255, .12);
  display: grid; place-items: center; border-radius: 50%; cursor: pointer;
  transition: background .25s var(--ds-ease);
}
.ds-lb-close:hover, .ds-lb-nav:hover { background: rgba(255, 255, 255, .28); }
.ds-lb-close { top: 18px; right: 22px; width: 42px; height: 42px; font-size: 1.2rem; }
.ds-lb-nav { top: 50%; transform: translateY(-50%); width: 46px; height: 46px; font-size: 1.4rem; }
.ds-lb-prev { left: max(.5rem, 2vw); }
.ds-lb-next { right: max(.5rem, 2vw); }
.ds-lb-nav[hidden] { display: none; }
@media (max-width: 575px) {
  .ds-lb-nav { width: 38px; height: 38px; top: auto; bottom: 1rem; transform: none; }
  .ds-lb-stage > img, .ds-lb-stage > video { max-height: 62vh; }
}

/* ---------- no logo carries a border ------------------------------------
   The client wants logos to sit on the page unframed. Backgrounds that give a
   transparent PNG something to read against are fine; a drawn edge is not.  */
.cv-badge, .cv-badge img,
.ph-badge, .ph-badge img,
.profile-logo, .profile-logo img,
.rank-item .thumb, .logo-marquee img,
.compare-head-card img { border: 0; outline: 0; }

/* A card with no badge needs the body to clear the cover on its own. */
.ds-card .cv-band + .cv-body { padding-top: 1.1rem; }
.person-card .cv-body h3 { margin-top: .1rem; }
.person-card .role { font-size: .8rem; color: var(--ds-muted); line-height: 1.4; min-height: 2.2em; }

/* Cards in a row must line their footers up whatever the title wraps to. */
.company-card, .product-card, .person-card { display: flex; flex-direction: column; }
.company-card > .card-foot, .product-card > .card-foot { margin-top: auto; }
.view-list .company-card, .view-list .product-card, .view-list .person-card { flex-direction: row; }

/* =====================================================================
   AD ZONES
   Sold space. Every zone reserves its aspect ratio up front so the page
   never jumps while a creative loads, and an unsold zone prints nothing.
   ===================================================================== */
.promo-zone {
  position: relative; border-radius: var(--ds-radius-lg); overflow: hidden;
  background: var(--ds-navy-800);
}
.promo-zone .promo-track { display: grid; }
.promo-zone .promo-slide {
  grid-area: 1 / 1; position: relative; display: block;
  aspect-ratio: var(--promo-ratio, 16 / 4);
  text-decoration: none; color: #fff; isolation: isolate;
}
/* Non-slider zones stack their creatives instead of overlapping them. */
.promo-zone:not(.is-slider) .promo-track { gap: .75rem; }
.promo-zone:not(.is-slider) .promo-slide { grid-area: auto; }

.promo-zone.is-slider .promo-slide { opacity: 0; visibility: hidden; transition: opacity .5s var(--ds-ease); }
.promo-zone.is-slider .promo-slide.is-on { opacity: 1; visibility: visible; }

.promo-media { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
/* Just enough shade under the copy to keep it readable — the creative is
   what the advertiser paid for, so it must still be the thing you see. */
.promo-scrim {
  position: absolute; inset: 0;
  background: linear-gradient(90deg, rgba(5,13,28,.88) 0%, rgba(5,13,28,.62) 34%,
                                     rgba(5,13,28,.18) 62%, rgba(5,13,28,0) 100%);
}

.promo-copy {
  position: absolute; inset: 0; z-index: 2; min-height: 0;
  display: flex; flex-direction: column; align-items: flex-start; justify-content: center;
  gap: .5rem; padding: clamp(1.1rem, 4vw, 3rem); max-width: 62ch;
}
/* With no creative uploaded the copy panel IS the ad, so it fills the frame
   rather than sitting in a half-width band with bare card behind it. */
.promo-copy.on-plain { background: var(--ds-grad-hero); max-width: none; }
.promo-copy.on-plain .promo-title, .promo-copy.on-plain .promo-sub { max-width: 62ch; }
.promo-title {
  font-family: var(--ds-font-display); font-weight: 800; line-height: 1.1;
  font-size: clamp(1.25rem, 3.2vw, 2.6rem); text-wrap: balance;
}
.promo-sub { font-size: clamp(.85rem, 1.3vw, 1.02rem); color: rgba(255,255,255,.82); max-width: 54ch; }
.promo-cta {
  margin-top: .35rem; display: inline-flex; align-items: center; gap: .45rem;
  background: var(--ds-gold-500); color: var(--ds-navy-900);
  font-weight: 700; font-size: .9rem; padding: .55rem 1.1rem; border-radius: 999px;
  transition: transform .25s var(--ds-ease);
}
.promo-slide:hover .promo-cta { transform: translateX(3px); }

/* Disclosure, not decoration - kept small and out of the creative's way. */
.promo-label {
  position: absolute; top: .55rem; right: .55rem; z-index: 3;
  font-size: .6rem; font-weight: 700; letter-spacing: .1em; text-transform: uppercase;
  background: rgba(5,13,28,.6); color: rgba(255,255,255,.85);
  padding: .12rem .4rem; border-radius: 4px; backdrop-filter: blur(4px);
}

.promo-nav {
  position: absolute; top: 50%; transform: translateY(-50%); z-index: 4;
  width: 38px; height: 38px; border-radius: 50%; border: 0;
  background: rgba(5,13,28,.45); color: #fff; display: grid; place-items: center;
  opacity: 0; transition: opacity .25s var(--ds-ease), background .25s var(--ds-ease);
}
.promo-nav.prev { left: .7rem; }
.promo-nav.next { right: .7rem; }
.promo-zone:hover .promo-nav, .promo-nav:focus-visible { opacity: 1; }
.promo-nav:hover { background: rgba(5,13,28,.75); }

.promo-dots {
  position: absolute; left: 0; right: 0; bottom: .7rem; z-index: 4;
  display: flex; justify-content: center; gap: .35rem;
}
.promo-dots button {
  width: 8px; height: 8px; padding: 0; border: 0; border-radius: 999px;
  background: rgba(255,255,255,.45); transition: width .3s var(--ds-ease), background .3s var(--ds-ease);
}
.promo-dots button.is-on { width: 22px; background: var(--ds-gold-500); }

/* ---------- hero ---------------------------------------------------- */
.hero-promo { padding: 1rem 0 0; }
.hero-promo .promo-zone { border-radius: var(--ds-radius-lg); }

/* The search moved out of the hero, so it needs to look deliberate rather
   than orphaned: a raised card straddling the ad above and the page below. */
.hero-search-strip { padding: 1.1rem 0 1.6rem; }
.hero-search-strip .hero-search {
  background: #fff; border: 1px solid var(--ds-border); border-radius: var(--ds-radius-lg);
  padding: 1rem 1.1rem; box-shadow: 0 12px 34px rgba(10,25,48,.09);
  max-width: none; width: 100%;
}
.hero-search-strip .hero-search form,
.hero-search-strip .search-field { max-width: none; }
.hero-search-strip .hero-search .search-tabs button { color: var(--ds-navy-700); }
.hero-search-strip .hero-hints { color: var(--ds-muted); }
.hero-search-strip .hero-hints a { color: var(--ds-primary); }
.hero-search-strip .stat-strip { margin-top: 1.1rem; }

@media (max-width: 640px) {
  .promo-zone { border-radius: var(--ds-radius); }
  .promo-nav { display: none; }
  .hero-promo { padding-top: .7rem; }
  .hero-search-strip { padding: .8rem 0 1.1rem; }
  .hero-search-strip .hero-search { padding: .8rem; }
}

/* TinyMCE can emit this and Bootstrap 5 has no equivalent utility. */
.text-justify { text-align: justify; }

/* Ad copy scales with the zone. The hero gets headline treatment; a strip or
   a square tile would look absurd at the same size, and the copy would crowd
   out the creative the advertiser is paying to show. */
.promo-zone--hero_inner .promo-title,
.promo-zone--listing_top .promo-title,
.promo-zone--home_mid .promo-title,
.promo-zone--blog_top .promo-title { font-size: clamp(1.05rem, 1.9vw, 1.65rem); }

.promo-zone--hero_inner .promo-sub,
.promo-zone--listing_top .promo-sub,
.promo-zone--home_mid .promo-sub,
.promo-zone--blog_top .promo-sub { font-size: clamp(.8rem, 1vw, .92rem); }

.promo-zone--hero_inner .promo-copy,
.promo-zone--listing_top .promo-copy,
.promo-zone--home_mid .promo-copy,
.promo-zone--blog_top .promo-copy { padding: clamp(.9rem, 2.4vw, 1.8rem); gap: .35rem; }

.promo-zone--detail_inline .promo-title { font-size: clamp(1.05rem, 1.7vw, 1.5rem); }
.promo-zone--detail_inline .promo-copy { padding: clamp(.9rem, 2vw, 1.6rem); gap: .35rem; }

.promo-zone--footer_cta .promo-title { font-size: clamp(1.15rem, 2.1vw, 1.8rem); }

/* Square sidebar tiles: copy sits at the bottom, not centred over the middle
   of the picture. */
.promo-zone--listing_side .promo-copy,
.promo-zone--detail_side .promo-copy {
  justify-content: flex-end; padding: .9rem; gap: .3rem; max-width: none;
}
.promo-zone--listing_side .promo-title,
.promo-zone--detail_side .promo-title { font-size: 1.02rem; line-height: 1.25; }
.promo-zone--listing_side .promo-sub,
.promo-zone--detail_side .promo-sub { font-size: .8rem; }
.promo-zone--listing_side .promo-cta,
.promo-zone--detail_side .promo-cta { font-size: .8rem; padding: .4rem .8rem; }
.promo-zone--listing_side .promo-scrim,
.promo-zone--detail_side .promo-scrim {
  background: linear-gradient(180deg, rgba(5,13,28,0) 30%, rgba(5,13,28,.85) 100%);
}

/* ---------- home hero: slider + side rail --------------------------------
   The rail is not decoration. A rotating slot is only on screen part of the
   time, so the two fixed cards beside it are the slot a buyer takes when they
   want to be seen on every single page load. */
.hero-grid {
  display: grid; gap: .9rem;
  grid-template-columns: minmax(0, 2.3fr) minmax(0, 1fr);
  align-items: stretch;
}
.hero-main, .hero-rail { min-width: 0; }
.hero-main .promo-zone { height: 100%; }
.hero-main .promo-slide { height: 100%; aspect-ratio: auto; min-height: 390px; }

/* Two cards, splitting the slider's height between them. */
.hero-rail .promo-zone { height: 100%; background: transparent; border-radius: 0; overflow: visible; }
.hero-rail .promo-track {
  height: 100%; gap: .9rem;
  grid-auto-rows: 1fr; grid-auto-flow: row;
}
.hero-rail .promo-slide {
  aspect-ratio: auto; height: 100%; min-height: 0;
  border-radius: var(--ds-radius); overflow: hidden;
}

@media (max-width: 991px) {
  .hero-grid { grid-template-columns: 1fr; }
  .hero-main .promo-slide { min-height: 0; aspect-ratio: 16 / 11.7; }
  .hero-rail .promo-track { grid-auto-flow: column; grid-auto-columns: 1fr; }
  .hero-rail .promo-slide { aspect-ratio: 16 / 9; }
}
/* The rail used to stack on the narrowest phones, which gave two secondary
   promos more of the screen than the hero itself. Side by side they stay
   visible and cost one band instead of two. */
/* The rail on a phone.
   Side by side, each card is about 170px wide — not enough for a headline and
   a button, so the button was being cut in half. Stacked but short gives the
   copy the full width, and two 16/5 bands together are still less than the
   two 16/9 bands this replaced. */
@media (max-width: 575px) {
  .hero-rail .promo-track { grid-auto-flow: row; gap: .5rem; }

  /* Height comes from the copy, not from a ratio. A fixed 16/5 band clipped
     the top of a two-line headline the moment the illustration took its share
     of the width; letting the card grow means nothing is ever cut. The two
     cards still finish level because the grid row stretches them. */
  .hero-rail .promo-slide { aspect-ratio: auto; min-height: 112px; }
  .promo-zone--hero_side .promo-copy {
    position: relative; inset: auto;
    padding: .85rem 32% .85rem 1rem; gap: .3rem;
  }
  .promo-zone--hero_side .promo-title { font-size: .98rem; line-height: 1.25; }
  .promo-zone--hero_side .promo-sub { font-size: .78rem; }
  .promo-zone--hero_side .promo-cta { font-size: .76rem; padding: .34rem .8rem; }
}

/* Flex children shrink by default, so the three lines of copy were squashing
   into each other instead of clamping. Pin them to their content height and
   let -webkit-line-clamp do the trimming. */
.promo-zone--hero_side .promo-copy > * { flex: 0 0 auto; }

/* Hero rail cards are pale illustrations, so their copy is dark and there is
   no scrim over them - a dark wash would ruin the artwork it sits on. */
.promo-zone--hero_side .promo-scrim { display: none; }
/* The card's height is set by the slider beside it, so the copy has to fit
   whatever that turns out to be: everything clamps rather than spilling out. */
.promo-zone--hero_side .promo-copy {
  max-width: 60%; padding: clamp(.8rem, 1.6vw, 1.15rem); gap: .35rem;
  justify-content: center; overflow: hidden;
}
.promo-zone--hero_side .promo-title {
  color: var(--ds-navy-800); font-family: var(--ds-font-body); font-weight: 700;
  font-size: clamp(.92rem, 1.15vw, 1.08rem); line-height: 1.25;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.promo-zone--hero_side .promo-sub {
  color: rgba(15, 30, 55, .72); font-size: .76rem; line-height: 1.4;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.promo-zone--hero_side .promo-cta {
  background: #fff; color: var(--ds-navy-800); flex: none; white-space: nowrap;
  border: 1px solid rgba(15, 30, 55, .18); font-size: .76rem; padding: .35rem .75rem;
  box-shadow: 0 2px 6px rgba(15, 30, 55, .08);
}
.promo-zone--hero_side .promo-slide:hover .promo-cta { background: var(--ds-navy-800); color: #fff; }
.promo-zone--hero_side .promo-label { background: rgba(15, 30, 55, .5); }

@media (max-width: 575px) {
  .promo-zone--hero_side .promo-copy { max-width: 68%; }
}

/* Nothing booked in the rail: the slider takes the full width instead of
   leaving a third of the hero blank. */
.hero-grid.no-rail { grid-template-columns: 1fr; }
.hero-grid.no-rail .hero-main .promo-slide { min-height: 0; aspect-ratio: 16 / 7.15; }

/* =======================================================================
   Fixes: ad zones vs. the layout they were dropped into
   ======================================================================= */

/* ---------- unsold hero ------------------------------------------------
   A house panel has no creative behind it, so it paints its own ground.
   Same shape and weight as a booked slide, so the page does not change
   height the day the first advertiser goes live. */
.promo-zone.is-house .promo-slide { background: var(--ds-grad-hero); }
.promo-zone.is-house .promo-slide::after {
  content: ''; position: absolute; inset: 0; opacity: .5; pointer-events: none;
  background:
    radial-gradient(circle at 14% 120%, rgba(11,87,208,.55), transparent 60%),
    repeating-linear-gradient(115deg, rgba(255,255,255,.05) 0 14px, transparent 14px 30px);
}
/* The slide already paints the ground, so the copy panel must not paint a
   second one over part of it. */
.promo-zone.is-house .promo-copy,
.promo-zone.is-house .promo-copy.on-plain { background: none; max-width: none; z-index: 2; }
.promo-zone.is-house .promo-title { color: #fff; }
.promo-zone.is-house .promo-sub   { color: rgba(255,255,255,.78); }
.hero-rail .promo-zone.is-house .promo-track { display: grid; }

/* ---------- stat strip on a light ground -------------------------------
   The counters were written for the old dark hero and inherited white text.
   The strip now sits on the page background, where white on white is
   invisible - which is exactly how it rendered: four coloured icons and
   nothing beside them. */
.hero-search-strip .stat-card {
  background: #fff; border-color: var(--ds-border);
  box-shadow: var(--ds-shadow-xs); backdrop-filter: none;
}
.hero-search-strip .stat-card:hover { background: #fff; box-shadow: 0 10px 26px rgba(10,25,48,.10); }
.hero-search-strip .stat-card .value { color: var(--ds-navy-800); }
.hero-search-strip .stat-card .label { color: var(--ds-muted); }

/* ---------- profile badge must sit above the cover ---------------------
   .ph-cover is positioned and the badge was not, so the cover painted over
   the 46px the badge is pulled up by and sliced the top off every logo. */
.ph-badge { position: relative; z-index: 2; }

/* ---------- listing sidebar: one sticky column, not two ----------------
   The filter panel was the sticky element and the ad was a sibling below
   it. A panel up to a full viewport tall left the ad nowhere to go, and
   because both are positioned the ad painted straight over the filters.
   The column sticks now; the panel and the ad ride inside it. */
@media (min-width: 992px) {
  .listing-wrap > aside {
    align-self: start;
    position: sticky; top: calc(var(--ds-header-h) + 12px);
    max-height: calc(100vh - var(--ds-header-h) - 28px);
    overflow-y: auto; overscroll-behavior: contain;
    scrollbar-width: thin; scrollbar-color: var(--ds-steel-300) transparent;
  }
  .listing-wrap > aside::-webkit-scrollbar { width: 8px; }
  .listing-wrap > aside::-webkit-scrollbar-thumb {
    background: var(--ds-steel-300); border-radius: 99px;
    border: 2px solid var(--ds-bg, #fff); background-clip: padding-box;
  }
  .listing-wrap > aside::-webkit-scrollbar-track { background: transparent; }
  /* The column is the scroll container only as a backstop. Inside it the
     filters take whatever height is left and scroll on their own, so the
     booked ad below them stays visible without the reader hunting for it —
     an ad that has to be scrolled to is an ad nobody sees. */
  .listing-wrap > aside { display: flex; flex-direction: column; }
  .listing-wrap > aside .filter-panel {
    position: static; max-height: none;
    flex: 1 1 auto; min-height: 0; overflow-y: auto;
  }
  /* Filters come first: they are what the page is for. The ad takes the
     space left over and gives it back on a short screen rather than
     squeezing the filter list down to a single row. */
  .listing-wrap > aside .filter-panel { min-height: 260px; }
  /* Never clipped - a half-shown creative is not what was sold. */
  .listing-wrap > aside > .promo-zone { flex: 0 0 auto; }
}

/* ---------- detail sidebar --------------------------------------------
   The ad now sits above the sticky block rather than inside it, so the
   panels stick from the same offset they always did. Belt and braces: cap
   the sticky block so a tall sidebar can still be read to the end. */
.detail-side-ad { margin-bottom: 1rem; }

/* ---------- footer call to action --------------------------------------
   It sat flush against the footer's top edge with no air above it. */
.promo-zone--footer_cta { margin-top: .5rem; }

/* ---------- desktop keeps one search box, not two ----------------------
   The header already carries a search field on desktop, so the strip under
   the hero was asking the same question twice. On mobile the header field
   is hidden, so the strip is the only search there and stays. */
@media (min-width: 992px) {
  .hero-search-strip .hero-search { display: none; }
  .hero-search-strip { padding-top: 1.4rem; }
  .hero-search-strip .stat-strip { margin-top: 0; }
}

/* ---------- media count on a listing card ------------------------------
   Says at a glance which records carry photos and video, so the gallery is
   discoverable from the listing rather than only after a click. */
.cv-media {
  position: absolute; right: .6rem; bottom: .6rem; z-index: 2;
  display: flex; gap: .3rem; pointer-events: none;
}
.cv-media > span {
  display: inline-flex; align-items: center; gap: .28rem;
  background: rgba(5,13,28,.62); color: #fff;
  font-size: .72rem; font-weight: 600; line-height: 1;
  padding: .3rem .48rem; border-radius: 999px;
  backdrop-filter: blur(4px);
}
.cv-media i { font-size: .82rem; }

/* =======================================================================
   Member-submitted listings
   ======================================================================= */

/* The status is what the member came to the page to read, so it carries
   colour and an icon rather than sitting in a table cell. */
.listing-state {
  display: inline-flex; align-items: center; gap: .35rem;
  font-size: .74rem; font-weight: 700; letter-spacing: .02em;
  padding: .24rem .6rem; border-radius: 999px; white-space: nowrap;
}
.listing-state i { font-size: .82rem; }
.listing-state.st-pending  { background: #fff5e0; color: #8a5a00; }
.listing-state.st-live     { background: #e6f6ec; color: #10693a; }
.listing-state.st-rejected { background: #fdeaea; color: #a11b1b; }
.listing-state.st-draft    { background: var(--ds-steel-100, #eef2f7); color: var(--ds-steel-700, #4a5b73); }

/* A rejection is the one thing on this page a member must not miss. */
.listing-reason {
  margin-top: .6rem; padding: .6rem .75rem; font-size: .84rem;
  background: #fdeaea; border-left: 3px solid #d64545; border-radius: 6px;
  color: #7a1616;
}

/* Forty categories in a single column would bury the rest of the form. */
.listing-cats {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: .35rem .9rem;
  max-height: 320px; overflow-y: auto; padding-right: .3rem;
  scrollbar-width: thin; scrollbar-color: var(--ds-steel-300) transparent;
}
.listing-cat {
  display: flex; align-items: center; gap: .5rem; font-size: .88rem;
  padding: .18rem 0; cursor: pointer; color: var(--ds-text);
}
.listing-cat input { accent-color: var(--ds-primary); width: 15px; height: 15px; flex: none; }

/* =======================================================================
   Ranking rows — a shortlist you can read without opening every entry
   ======================================================================= */
.rank-item .rank-body { flex: 1 1 auto; min-width: 0; }

.rank-sub {
  display: flex; flex-wrap: wrap; gap: .2rem .9rem; font-size: .85rem; margin-bottom: .45rem;
}

.rank-cats { display: flex; flex-wrap: wrap; gap: .3rem; margin-bottom: .5rem; }
.rank-cat {
  font-size: .72rem; font-weight: 600; letter-spacing: .01em;
  padding: .2rem .55rem; border-radius: 999px;
  background: var(--ds-blue-050); color: var(--ds-primary);
}
.rank-cat.is-more { background: var(--ds-steel-100); color: var(--ds-steel-700); }

.rank-desc { font-size: .88rem; margin: 0 0 .7rem; }

/* The facts are the point of the row, so they get a grid rather than another
   run-on line of muted text. */
.rank-facts {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(130px, 1fr));
  gap: .5rem .9rem; margin: 0 0 .85rem; padding: .7rem .85rem;
  background: var(--ds-bg-soft, #f6f8fb); border-radius: 10px;
}
.rank-facts > div { min-width: 0; }
.rank-facts dt {
  font-size: .68rem; font-weight: 700; text-transform: uppercase; letter-spacing: .05em;
  color: var(--ds-steel-500, #7b8aa1); margin: 0 0 .12rem;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
/* Values wrap to a second line rather than truncating — "Research Organisation"
   cut to "Research Orga…" tells the reader nothing. */
.rank-facts dd {
  margin: 0; font-size: .87rem; font-weight: 600; color: var(--ds-navy-800);
  line-height: 1.3; overflow: hidden;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
}

.rank-foot {
  display: flex; align-items: center; gap: .9rem; flex-wrap: wrap; font-size: .8rem;
  padding-top: .7rem; border-top: 1px solid var(--ds-steel-100);
}
.rank-actions { display: flex; align-items: center; gap: .45rem; margin-left: auto; }

@media (max-width: 575px) {
  .rank-item { gap: .7rem; padding: .9rem; flex-wrap: wrap; }
  .rank-item .rank-no { width: 40px; height: 40px; font-size: 1.15rem; border-radius: 11px; }
  .rank-item .thumb { width: 54px; height: 54px; }
  .rank-facts { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .rank-actions { width: 100%; margin-left: 0; }
  .rank-actions .btn { flex: 1; justify-content: center; }
}

/* =======================================================================
   Comparison table
   ======================================================================= */

/* The stuck header was 210px tall, so every row emerged from under a block a
   quarter of the screen deep and the first one always looked sliced in half.
   A compact card and a real shadow make it read as a floating header. */
.compare-table thead th { box-shadow: 0 6px 14px -8px rgba(10, 25, 48, .35); }
.compare-head-card img { height: 56px; }
.compare-head-card .name { font-size: .9rem; }

/* Nothing should sit under the sticky header when a link jumps to a row. */
.compare-table-wrap { scroll-padding-top: 0; }

@media (max-width: 991px) {
  /* On a short screen a sticky header this tall leaves almost nothing to
     read, so the row labels stay pinned and the header scrolls away. */
  .compare-table thead th { position: static; top: auto; }
  .compare-table-wrap { scroll-padding-top: 0; }
}

@media (max-width: 640px) {
  /* Fit the labels plus two products on a phone instead of one and a sliver.
     The label column has to be pinned to a width for both head and body or the
     empty header cell claims 190px of a 358px screen on its own. */
  .compare-table { min-width: 0; font-size: .86rem; }
  .compare-table th, .compare-table td { padding: .6rem .55rem; font-size: .84rem; }
  .compare-label-head,
  .compare-table tbody th {
    width: 104px; min-width: 104px; max-width: 104px; font-size: .78rem;
  }
  .compare-slot-head { min-width: 124px; }
  /* The pinned column needs an edge, or values scroll under it invisibly. */
  .compare-table tbody th { box-shadow: 6px 0 8px -8px rgba(10, 25, 48, .4); }
  .compare-table .group-row th { font-size: .82rem; padding: .5rem .6rem; }
  .compare-head-card { min-width: 124px; }
  .compare-head-card img { height: 44px; margin-bottom: .35rem; }
  .compare-head-card .name { font-size: .82rem; }
  .compare-head-card .brand { font-size: .72rem; }
  .compare-head-card .btn { font-size: .76rem; padding: .35rem .6rem; width: 100%; }
  .compare-head-card .remove { width: 20px; height: 20px; font-size: .64rem; }
}

/* A table that scrolls sideways has to say so — on a phone the second product
   is off-screen and there is nothing else to suggest it exists. */
.compare-swipe-hint {
  display: none; align-items: center; gap: .4rem;
  font-size: .8rem; color: var(--ds-muted); margin-bottom: .5rem;
}
@media (max-width: 991px) { .compare-swipe-hint { display: flex; } }

/* An editor-written row sits alongside generated specification rows, so it
   carries a quiet marker rather than blending in completely. */
.compare-table tr.row-editorial th { box-shadow: inset 3px 0 0 var(--ds-gold-500); }

/* =======================================================================
   News board — one lead story with a digest beside it
   =======================================================================
   The hard part is that the block has to look deliberate with three stories
   and with five. Both columns therefore stretch to the same height and the
   lead photograph grows to fill whatever height the digest sets, so there is
   never a tall column of white beside a short list. */
.news-board {
  display: grid; grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr);
  align-items: stretch;
  background: #fff; border: 1px solid var(--ds-border); border-radius: var(--ds-radius-lg);
  overflow: hidden; box-shadow: var(--ds-shadow-xs);
}

/* ---------- the lead ---------- */
.news-lead {
  display: flex; flex-direction: column; min-width: 0;
  padding: 1.15rem; border-right: 1px solid var(--ds-border);
}
.news-lead-img {
  position: relative; display: block; flex: 1 1 auto;
  min-height: 240px; border-radius: var(--ds-radius); overflow: hidden;
  background: var(--ds-steel-100);
}
.news-lead-img img {
  position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; display: block;
  transition: transform .6s var(--ds-ease);
}
.news-lead:hover .news-lead-img img { transform: scale(1.04); }
.news-tag {
  position: absolute; left: .7rem; top: .7rem; z-index: 2;
  background: rgba(255,255,255,.94); color: var(--ds-primary);
  font-size: .72rem; font-weight: 700; padding: .26rem .6rem; border-radius: 999px;
  backdrop-filter: blur(4px);
}
.news-lead-body { flex: 0 0 auto; padding-top: .9rem; }
.news-lead-body h3 {
  font-size: 1.24rem; line-height: 1.3; margin: .28rem 0 .45rem; text-wrap: balance;
}
.news-lead-body h3 a { color: var(--ds-navy-800); }
.news-lead-body h3 a:hover { color: var(--ds-primary); }
.news-lead-body p {
  font-size: .89rem; line-height: 1.6; margin: 0;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}

/* ---------- the digest ---------- */
.news-digest { display: flex; flex-direction: column; padding: 1.15rem; min-width: 0; }

/* Each story takes an equal share of the column, so two fill it as
   convincingly as four instead of huddling in the middle. */
.news-item {
  flex: 1 1 0; display: flex; gap: .9rem; align-items: center; min-height: 0;
  padding: .9rem 0; border-bottom: 1px solid var(--ds-steel-100);
}
.news-item:first-child { padding-top: 0; }
.news-item:last-child { padding-bottom: 0; border-bottom: 0; }
.news-item-img {
  flex: none; width: 132px; aspect-ratio: 16 / 10; border-radius: 10px;
  overflow: hidden; background: var(--ds-steel-100);
}
.news-item-img img {
  width: 100%; height: 100%; object-fit: cover; display: block;
  transition: transform .5s var(--ds-ease);
}
.news-item:hover .news-item-img img { transform: scale(1.05); }
.news-item-body { min-width: 0; }
.news-item-body h4 {
  font-size: .94rem; line-height: 1.4; margin: .2rem 0 0; font-family: var(--ds-font-body);
}
.news-item-body h4 a { color: var(--ds-navy-800); font-weight: 700; }
.news-item-body h4 a:hover { color: var(--ds-primary); }

.news-when {
  font-size: .74rem; color: var(--ds-muted); font-weight: 600;
  text-transform: uppercase; letter-spacing: .04em;
}

@media (max-width: 991px) {
  .news-board { grid-template-columns: 1fr; }
  .news-lead { border-right: 0; border-bottom: 1px solid var(--ds-border); }
  .news-lead-img { min-height: 0; aspect-ratio: 16 / 9; }
  .news-item { flex: 0 0 auto; }
}
@media (max-width: 480px) {
  .news-lead, .news-digest { padding: .9rem; }
  .news-item-img { width: 104px; }
  .news-lead-body h3 { font-size: 1.08rem; }
}

/* Comparison cards on the home page. */
.cmp-card { transition: transform .3s var(--ds-ease), box-shadow .3s var(--ds-ease); }
.cmp-card:hover { transform: translateY(-3px); box-shadow: var(--ds-shadow); }
.cmp-card-title {
  font-weight: 700; color: var(--ds-navy-800); line-height: 1.4; font-size: .98rem;
}
.cmp-card-vs { font-size: .74rem; color: var(--ds-muted); font-weight: 600; white-space: nowrap; }

/* The Compare link in the utility strip becomes a menu once an editor has
   published comparisons, so the work is reachable from every page. */
.hdr-compare { position: relative; }
.hdr-compare > a { display: inline-flex; align-items: center; }
.hdr-compare-menu { min-width: 300px; max-width: 380px; }
.hdr-compare-menu .dropdown-header {
  font-size: .7rem; text-transform: uppercase; letter-spacing: .06em;
  font-weight: 700; color: var(--ds-steel-500, #7b8aa1); padding: .5rem .9rem .2rem;
}
/* The strip this sits in is dark and colours its links white, which the menu
   would otherwise inherit — white text on a white dropdown. */
.hdr-compare-menu .dropdown-item,
.hdr-compare-menu .dropdown-item span,
.hdr-compare-menu .dropdown-item i {
  color: var(--ds-text); display: inline;
}
.hdr-compare-menu .dropdown-item {
  display: flex; align-items: flex-start; gap: .55rem; white-space: normal;
}
.hdr-compare-menu .dropdown-item i { margin-top: .18rem; flex: none; color: var(--ds-primary); }
.hdr-compare-menu .dropdown-item span { line-height: 1.35; font-size: .86rem; }
.hdr-compare-menu .dropdown-item:hover,
.hdr-compare-menu .dropdown-item:hover span { background: var(--ds-blue-050); color: var(--ds-primary); }

/* =======================================================================
   Home page splash
   =======================================================================
   Shown only on the home page. Everything here is defensive: the fade runs
   from CSS as well as JavaScript, so a blocked script or a stalled image
   still ends with the curtain gone. */
#ds-splash {
  position: fixed; inset: 0; z-index: 4000;
  display: grid; place-items: center;
  background: #fff;
  animation: ds-splash-out .5s var(--ds-ease, ease) 3.2s forwards;
}
.ds-splash-inner {
  display: flex; flex-direction: column; align-items: center; gap: 1.15rem;
}
.ds-splash-inner img,
.ds-splash-word {
  animation: ds-splash-rise .7s var(--ds-ease-out, cubic-bezier(.2,.8,.2,1)) both;
}
.ds-splash-inner img { height: 56px; width: auto; object-fit: contain; }
.ds-splash-word {
  font-family: var(--ds-font-display, sans-serif); font-weight: 800;
  font-size: 1.6rem; letter-spacing: .01em; color: var(--ds-navy-800, #0a1930);
}

/* A determinate-looking sweep rather than a spinner — it reads as "loading",
   not as "something is stuck". */
.ds-splash-bar {
  display: block; width: 150px; height: 3px; border-radius: 999px;
  background: var(--ds-steel-100, #eef2f7); overflow: hidden;
}
.ds-splash-bar i {
  display: block; height: 100%; width: 40%; border-radius: 999px;
  background: var(--ds-grad-blue, linear-gradient(90deg, #0b57d0, #3b82f6));
  animation: ds-splash-sweep 1.1s ease-in-out infinite;
}

#ds-splash.is-gone { animation: ds-splash-out .45s var(--ds-ease, ease) forwards; }

@keyframes ds-splash-rise {
  from { opacity: 0; transform: translateY(10px) scale(.97); }
  to   { opacity: 1; transform: none; }
}
@keyframes ds-splash-sweep {
  0%   { transform: translateX(-110%); }
  100% { transform: translateX(270%); }
}
@keyframes ds-splash-out {
  to { opacity: 0; visibility: hidden; }
}

/* Someone who asked for less motion gets no curtain at all. */
@media (prefers-reduced-motion: reduce) {
  #ds-splash { display: none !important; }
}

/* ---------------------------------------------------------------------------
   Custom HTML ad creatives (AdSense and similar)

   A network tag brings its own iframe and its own dimensions, so this zone
   deliberately has no aspect-ratio box and no overflow clipping — both would
   crop whatever the network decides to serve. It only supplies the outer
   spacing so a pasted block sits like every other zone on the page.
--------------------------------------------------------------------------- */
.promo-zone.is-code {
  position: relative;
  display: block;
  aspect-ratio: auto;
  min-height: 0;
  overflow: visible;
  background: none;
  border-radius: 0;
  box-shadow: none;
  text-align: center;
  margin-block: 1rem;
}
.promo-zone.is-code > ins,
.promo-zone.is-code iframe { max-width: 100%; }
.promo-label--code {
  position: absolute; top: -.55rem; left: 0;
  font-size: .62rem; letter-spacing: .08em; text-transform: uppercase;
  color: var(--ds-muted); background: transparent; padding: 0;
}

/* ---------------------------------------------------------------------------
   Thumbnail strip

   Ranking and comparison cards name records the reader cannot see. A row of
   overlapping marks turns "Top 10 Defence Companies in India" into something
   recognisable at a glance, and costs one line of vertical space.

   The overlap is done with a negative margin rather than absolute positioning
   so the strip still wraps and still measures correctly inside a flex card.
--------------------------------------------------------------------------- */
.thumb-strip { display: flex; align-items: center; flex-wrap: wrap; gap: 0; }
.thumb-strip-item {
  width: 34px; height: 34px; flex: 0 0 auto;
  border-radius: 9px; overflow: hidden;
  background: #fff; border: 1px solid var(--ds-border);
  box-shadow: 0 1px 2px rgba(15, 23, 42, .06);
  display: grid; place-items: center;
  margin-left: -8px;
}
.thumb-strip-item:first-child { margin-left: 0; }
.thumb-strip-item img { width: 100%; height: 100%; object-fit: contain; padding: 3px; }
/* Photographs fill the square instead of sitting letterboxed inside it. */
.thumb-strip-item.is-photo img { object-fit: cover; padding: 0; }
.thumb-strip-item.is-photo { background: var(--ds-steel-100); }
.thumb-strip-more {
  margin-left: .4rem;
  font-size: .74rem; font-weight: 700; color: var(--ds-muted);
  letter-spacing: .01em;
}
.thumb-strip--sm .thumb-strip-item { width: 28px; height: 28px; border-radius: 8px; margin-left: -7px; }
.thumb-strip--sm .thumb-strip-item:first-child { margin-left: 0; }

/* A result card for pages rather than records — rankings, comparisons, CMS
   pages. No image slot, because these have no picture and a placeholder here
   reads as a missing photo rather than as a page. */
.link-card { display: flex; flex-direction: column; }
.link-card-title {
  font-weight: 700; color: var(--ds-navy-800);
  line-height: 1.4; font-size: .95rem;
}
.link-card .link-more { margin-top: auto; }

/* ---------------------------------------------------------------------------
   Share bar

   At the top of a story rather than in the sidebar: sharing is decided when a
   reader arrives, and a rail control is invisible on a phone, where every
   share actually happens. Brand colours only on hover, so the row does not
   turn the top of an article into a strip of logos.
--------------------------------------------------------------------------- */
.sendto-bar {
  display: flex; align-items: center; gap: .85rem; flex-wrap: wrap;
  padding: .7rem 0 1rem;
  border-bottom: 1px solid var(--ds-border);
  margin-bottom: 1.5rem;
}
.sendto-label {
  font-size: .78rem; font-weight: 700; letter-spacing: .06em; text-transform: uppercase;
  color: var(--ds-muted); display: inline-flex; align-items: center; gap: .4rem;
}
.sendto-links { display: flex; align-items: center; gap: .4rem; flex-wrap: wrap; }

.sendto-chip {
  display: inline-flex; align-items: center; justify-content: center; gap: .4rem;
  min-width: 38px; height: 38px; padding: 0 .6rem;
  border: 1px solid var(--ds-border); border-radius: 10px;
  background: #fff; color: var(--ds-navy-700);
  font-size: .95rem; line-height: 1; cursor: pointer;
  transition: transform .15s ease, background-color .15s ease, border-color .15s ease, color .15s ease;
  text-decoration: none;
}
.sendto-chip span { font-size: .8rem; font-weight: 600; }
.sendto-chip:hover { transform: translateY(-2px); color: #fff; border-color: transparent; }
.sendto-chip.is-whatsapp:hover  { background: #25d366; }
.sendto-chip.is-facebook:hover  { background: #1877f2; }
.sendto-chip.is-x:hover         { background: #000; }
.sendto-chip.is-linkedin:hover  { background: #0a66c2; }
.sendto-chip.is-telegram:hover  { background: #229ed9; }
.sendto-chip.is-reddit:hover    { background: #ff4500; }
.sendto-chip.is-pinterest:hover { background: #bd081c; }
.sendto-chip.is-email:hover     { background: var(--ds-navy-700); }
.sendto-chip.is-copy:hover,
.sendto-chip.is-native:hover    { background: var(--ds-navy-800); }

/* The OS share sheet only exists on devices that have one. */
.sendto-chip.is-native { display: none; }
.sendto-chip.is-native.is-on { display: inline-flex; }

@media (max-width: 575.98px) {
  .sendto-bar { gap: .5rem; }
  .sendto-label { width: 100%; }
  .sendto-chip { min-width: 40px; height: 40px; }
  .sendto-chip.is-copy span { display: none; }
}

/* ---------------------------------------------------------------------------
   Mobile corrections
--------------------------------------------------------------------------- */

/* The home page carried two search boxes on a phone: one in the header, always
   there, and a second immediately under the hero. The second one also had the
   scope tabs, which wrapped and clipped. The header search does the same job
   from every page, so below the tablet breakpoint the duplicate goes and the
   statistics strip moves up in its place. */
@media (max-width: 767.98px) {
  .hero-search-strip .hero-search { display: none; }
  .hero-search-strip .stat-strip { margin-top: 0; }
  .hero-search-strip { padding-top: .6rem; }
}

/* The header search keeps the full wording on a phone (it is the only search
   there now), so the text is scaled to fit rather than shortened. */
@media (max-width: 575.98px) {
  .hdr-search-field input[type="search"] { font-size: .86rem; }
  .hdr-search-field input[type="search"]::placeholder { font-size: .84rem; }
}

/* The rail illustrations are square; in a 16/5 band `cover` crops the top and
   bottom off them. Contained and pushed right, they read as artwork beside the
   copy instead of a cropped fragment behind it. */
/* Superseded — see "Hero rail cards on a phone" at the end of this file.
   `contain` fitted the illustration to the card's height and parked it on the
   right, which left the left half showing the card's own white background: a
   hard vertical seam down the middle of every rail card. */

/* ---------------------------------------------------------------------------
   Two overflow fixes found by measuring every element against the viewport.
--------------------------------------------------------------------------- */

/* 1. Card footer at 360px.
   Two cards to a row leaves about 166px, and "View Profile →" plus two icon
   buttons needs more than that — the buttons were sitting 10px past the card's
   right edge. Wrapping is the honest fix; shrinking the parts keeps it on one
   line in almost every case anyway. */
.company-card .card-foot,
.product-card .card-foot { flex-wrap: wrap; }
.company-card .card-foot .link-more,
.product-card .card-foot .link-more { min-width: 0; }

@media (max-width: 420px) {
  .company-card .card-foot,
  .product-card .card-foot { padding: .55rem .75rem; gap: .35rem; }
  .company-card .card-foot .link-more,
  .product-card .card-foot .link-more { font-size: .76rem; }
  .company-card .card-foot .btn-icon,
  .product-card .card-foot .btn-icon { width: 30px; height: 30px; font-size: .8rem; }
}

/* 2. The "Login / Register" label at tablet width.
   Below 992px the login control becomes a 42px square icon button, but the
   label inside it kept rendering and spilled past the right edge of the page.
   The icon carries the meaning at that size, so the words go.

   Note what is deliberately NOT done here: the mobile header puts the search
   on its own full-width row (`order: 3; flex-basis: 100%` above). Letting the
   search shrink onto the same row as the logo and the buttons — which an
   earlier version of this fix did — crushes it to about 90px and clips the
   placeholder mid-word. The stacked layout is the correct one; only the label
   needed removing. */
@media (max-width: 991.98px) {
  .hdr-login span { display: none !important; }
  .hdr-actions { flex: 0 0 auto; }
}

/* ---------------------------------------------------------------------------
   Strip ad zones on a phone

   These zones are quoted to advertisers at 16/3 and 16/4, which at 390px is
   about 100–130px tall — not enough for a headline, a line of copy and a
   button, so the button was being cut in half by the frame. On a phone the
   frame grows instead of cropping the creative's own message.
--------------------------------------------------------------------------- */
@media (max-width: 640px) {
  /* The ratio arrives as an inline custom property, and an inline style beats
     a stylesheet rule whatever the media query — so this overrides the
     resolved aspect-ratio rather than the variable behind it. */
  .promo-zone--blog_top,
  .promo-zone--listing_top,
  .promo-zone--home_mid,
  .promo-zone--footer_cta,
  .promo-zone--detail_inline { aspect-ratio: 16 / 8; }
  .promo-zone--blog_top .promo-slide,
  .promo-zone--listing_top .promo-slide,
  .promo-zone--home_mid .promo-slide,
  .promo-zone--footer_cta .promo-slide,
  .promo-zone--detail_inline .promo-slide { aspect-ratio: 16 / 8; }

  .promo-zone--blog_top .promo-title,
  .promo-zone--listing_top .promo-title,
  .promo-zone--home_mid .promo-title,
  .promo-zone--detail_inline .promo-title { font-size: 1.05rem; line-height: 1.25; }

  .promo-zone--blog_top .promo-sub,
  .promo-zone--listing_top .promo-sub,
  .promo-zone--home_mid .promo-sub,
  .promo-zone--detail_inline .promo-sub { font-size: .8rem; }

  .promo-zone--blog_top .promo-cta,
  .promo-zone--listing_top .promo-cta,
  .promo-zone--home_mid .promo-cta,
  .promo-zone--detail_inline .promo-cta { font-size: .78rem; padding: .4rem .85rem; }
}

/* ---------------------------------------------------------------------------
   A card that is not in a grid must not stretch

   `.ds-card { height: 100% }` exists so that cards sitting one-per-column in a
   grid all finish at the same line. Bootstrap columns stretch to the tallest
   column in the row, so inside a wide column that also holds other content —
   the lead story on /news, for example — that same rule stretched one card to
   the full height of the sidebar beside it. The result was a card with its
   picture and headline at the top and 430px of white below, pushing every
   other story off the screen. It reads exactly like an empty ad slot.

   A card alone in its column is a grid cell and still stretches. A card that
   shares its column with anything else sizes to its own content.
--------------------------------------------------------------------------- */
.ds-card:not(:only-child) { height: auto; }

/* ===========================================================================
   MOBILE REFINEMENT
   ---------------------------------------------------------------------------
   A phone is not a narrow desktop. The desktop layout scaled down honestly,
   but it spent its vertical space the way a 1440px screen can afford to:
   a 330px masthead to carry one line of text, 50px gaps between sections, a
   toolbar that occupied a third of the first screen. On a 390px screen that
   arithmetic means a visitor scrolls past furniture before reaching a single
   company.

   Everything below buys back vertical space and enlarges what a thumb has to
   hit. No layout is restructured — the same markup, tuned for the device.
   =========================================================================== */
@media (max-width: 767.98px) {

  /* ---- section rhythm ---------------------------------------------------
     Generous padding reads as calm on a desktop and as emptiness on a phone. */
  .section       { padding: 1.6rem 0; }
  .section-tight { padding: 1.15rem 0; }
  .section-head  { margin-bottom: 1rem; }
  .section-head .eyebrow { font-size: .68rem; padding: .26rem .6rem; margin-bottom: .5rem; }
  .section-head h2 { font-size: 1.35rem; line-height: 1.25; }
  .section-head p  { font-size: .88rem; line-height: 1.55; }

  /* ---- page masthead ----------------------------------------------------
     Was up to 4.2rem of padding above and 3rem below, around a display-size
     heading — a third of the screen before any content. */
  .page-masthead { padding: 1.5rem 0 1.4rem; }
  .page-masthead h1 { font-size: 1.7rem; line-height: 1.15; margin-bottom: .35rem; }
  .page-masthead p  { font-size: .9rem; line-height: 1.5; margin-bottom: 0; }
  .page-masthead .breadcrumb,
  .page-masthead nav { font-size: .78rem; margin-bottom: .5rem; }

  /* ---- listing toolbar --------------------------------------------------
     One line: filters, count, sort. It was wrapping to three. */
  /* Kept wrapping. A no-wrap scrolling strip was tried and it grew the
     toolbar past the viewport — its parent sizes to content, so the overflow
     dragged the whole column, ads and cards included, off the right edge.
     Smaller parts fit on one line anyway, and wrap safely when they do not. */
  .listing-toolbar {
    gap: .45rem; padding: .55rem .65rem; margin-bottom: .8rem;
    flex-wrap: wrap; min-width: 0; max-width: 100%;
  }
  .listing-toolbar .count { font-size: .8rem; }
  .listing-toolbar select { padding: .34rem .5rem; font-size: .8rem; }
  .listing-toolbar .btn { padding: .38rem .7rem; font-size: .82rem; }

  /* ---- cards ------------------------------------------------------------
     Shorter covers and tighter bodies put a second card on the first screen
     instead of one and a sliver of the next. */
  .company-card .cv-band,
  .product-card .cv-band { aspect-ratio: 16 / 7; }
  .ds-card .cv-body { padding: .5rem .9rem .85rem; }
  .ds-card .cv-body h3 { font-size: .98rem; line-height: 1.3; }
  .ds-card .cv-desc { font-size: .82rem; line-height: 1.45; }
  .ds-card .card-body { padding: .9rem; }

  /* A phone has no hover, so the press itself has to answer. */
  .ds-card:active { transform: scale(.985); transition-duration: .08s; }
  .ds-card:hover  { transform: none; box-shadow: var(--ds-shadow-xs); }

  /* ---- touch targets ----------------------------------------------------
     Anything a thumb aims at gets the 44px Apple and Google both ask for. */
  .btn-icon,
  .view-toggle .btn,
  .pagination .page-link { min-width: 44px; min-height: 44px; }
  .chip { padding: .45rem .85rem; }

  /* ---- typography -------------------------------------------------------
     The display face is set in viewport units; below 400px that lands on
     headings a phone cannot fit on two lines. */
  h1 { font-size: clamp(1.6rem, 7vw, 2.1rem); line-height: 1.15; }
  h2 { font-size: clamp(1.3rem, 5.6vw, 1.7rem); line-height: 1.2; }
  h3 { font-size: 1.05rem; }
  .lead { font-size: .95rem; }

  /* ---- panels -----------------------------------------------------------  */
  .panel-head { padding: .75rem .9rem; }
  .panel-head h2, .panel-head h3 { font-size: 1rem; }
  .panel-body { padding: .9rem; }

  /* ---- footer -----------------------------------------------------------
     Four stacked columns of links is a very long tail on a phone. */
  .foot-col { margin-bottom: 1.1rem; }
  .foot-col h4 { font-size: .92rem; margin-bottom: .5rem; }
  .foot-col a  { font-size: .86rem; }
}

/* The hero rail illustration reads better as a soft accent behind the copy
   than as a hard-edged panel beside it. */
@media (max-width: 575px) {
  .promo-zone--hero_side .promo-media { opacity: .5; object-position: right center; }
}

/* ---------------------------------------------------------------------------
   Footer columns collapse on a phone

   Three open columns put roughly twenty links between the last section of the
   page and the copyright line. Collapsed, the footer is three tappable
   headings — the links are all still there, one tap away.

   The transition runs on max-height rather than height because the lists have
   no fixed size; the value only has to be larger than any real column.
--------------------------------------------------------------------------- */
.foot-col.is-collapsible > h5 {
  display: flex; align-items: center; justify-content: space-between;
  cursor: pointer; user-select: none;
  padding: .7rem 0; margin: 0;
  border-bottom: 1px solid rgba(255, 255, 255, .09);
}
.foot-col.is-collapsible > h5::after {
  content: "\f282";                 /* bootstrap-icons chevron-down */
  font-family: bootstrap-icons;
  font-size: .8rem; font-weight: 400;
  opacity: .6;
  transition: transform .25s var(--ds-ease);
}
.foot-col.is-collapsible.is-open > h5::after { transform: rotate(180deg); }
.foot-col.is-collapsible > h5:focus-visible {
  outline: 2px solid var(--ds-accent); outline-offset: 3px; border-radius: 4px;
}

.foot-col.is-collapsible > ul {
  max-height: 0; overflow: hidden;
  margin: 0; padding: 0;
  transition: max-height .3s var(--ds-ease), padding .3s var(--ds-ease);
}
.foot-col.is-collapsible.is-open > ul {
  max-height: 40rem;
  padding: .75rem 0 .35rem;
}

/* The columns are their own dividers now, so the spacing between them goes. */
@media (max-width: 767.98px) {
  .foot-col.is-collapsible { margin-bottom: 0; }
}

/* ---------------------------------------------------------------------------
   Feature cards — ranking and comparison blocks

   These two blocks were the only ones on the home page without a picture, and
   beside the news board they read as a list of links rather than pages worth
   opening. They now lead with an image the same way a story does.

   The image is rarely a photograph someone commissioned. A ranking shows its
   own entries; a comparison shows the two or three things being compared, side
   by side with a VS between them — which states the whole proposition before a
   word of the title is read, and needs no artwork per record.
--------------------------------------------------------------------------- */
.feature-card {
  display: flex; flex-direction: column;
  overflow: hidden; color: inherit;
}

.feature-cover {
  position: relative; display: block;
  aspect-ratio: 16 / 9; overflow: hidden;
  background: linear-gradient(135deg, var(--ds-steel-100), #e8edf4);
}
.feature-cover > img {
  width: 100%; height: 100%; object-fit: cover; display: block;
  transition: transform .5s var(--ds-ease);
}
.feature-card:hover .feature-cover > img { transform: scale(1.05); }

/* A soft floor so the overlaid chips stay legible on any picture. */
.feature-scrim {
  position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(to top, rgba(5, 13, 28, .55) 0%, rgba(5, 13, 28, .12) 42%, transparent 70%);
}

/* ---- the mosaic a ranking falls back to ---- */
.feature-mosaic {
  position: absolute; inset: 0;
  display: grid; gap: 2px;
  padding: 0; background: var(--ds-border);
  grid-template-columns: repeat(2, 1fr);
  /* Auto rows size to their content, and a tile's image asks for 100% of an
     indefinite height — so the row grew to the logo's natural size and the
     cover clipped it. Equal fractions give every row a definite height, which
     is what `object-fit: contain` needs to do its job. */
  grid-auto-rows: 1fr;
}
.feature-mosaic--1 { grid-template-columns: 1fr; }
.feature-mosaic--2 { grid-template-columns: repeat(2, 1fr); }
.feature-mosaic--3 { grid-template-columns: repeat(3, 1fr); }
/* Deliberately block, not grid. A grid tile's implicit row is `auto`, so the
   image's `height: 100%` resolved against an indefinite height and fell back
   to the picture's natural size — 201px inside a 112px tile, clipped. A block
   box has the definite height the percentage needs. */
.feature-tile {
  display: block; overflow: hidden;
  background: #fff;
}
/* Without border-box the padding is added to the 100% and the logo overflows
   the tile, which crops exactly the thing the padding was there to protect. */
.feature-tile img { display: block; width: 100%; height: 100%; object-fit: contain; padding: 12%; box-sizing: border-box; }
.feature-tile.is-photo img { object-fit: cover; padding: 0; }

/* ---- the side-by-side a comparison falls back to ---- */
.versus {
  position: absolute; inset: 0;
  display: flex; align-items: stretch;
  background: var(--ds-border); gap: 2px;
}
.versus-pane {
  flex: 1 1 0; min-width: 0;
  display: block; overflow: hidden; background: #fff;
}
.versus-pane img { display: block; width: 100%; height: 100%; object-fit: contain; padding: 11%; box-sizing: border-box; }
.versus-pane.is-photo img { object-fit: cover; padding: 0; }

/* The VS badge sits on the seam, not inside either half. */
.versus-mark {
  position: relative; z-index: 3; align-self: center;
  width: 0; overflow: visible;
  display: grid; place-items: center;
}
.versus-mark::before {
  content: 'VS';
  position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%);
  font-family: var(--ds-font-display); font-weight: 800; font-size: .68rem; letter-spacing: .04em;
  color: var(--ds-navy-800); background: #fff;
  border: 2px solid var(--ds-border); border-radius: 999px;
  width: 30px; height: 30px; display: grid; place-items: center;
  box-shadow: 0 2px 8px rgba(10, 25, 48, .12);
}

/* ---- chips on the cover ---- */
.rank-chip {
  position: absolute; left: .7rem; top: .7rem; z-index: 3;
  width: 40px; height: 40px; border-radius: 12px;
  display: grid; place-items: center;
  background: var(--ds-grad-gold); color: var(--ds-navy-900);
  font-family: var(--ds-font-display); font-weight: 800; font-size: 1.02rem;
  box-shadow: 0 4px 12px rgba(10, 25, 48, .2);
}
.feature-tag, .feature-count, .feature-star {
  position: absolute; z-index: 3;
  font-size: .68rem; font-weight: 700; letter-spacing: .03em;
  padding: .26rem .55rem; border-radius: 7px;
  background: rgba(5, 13, 28, .72); color: #fff;
  backdrop-filter: blur(4px);
  max-width: 60%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.feature-tag   { left: .7rem;  bottom: .7rem; }
.feature-count { right: .7rem; bottom: .7rem; }
.feature-star  { right: .7rem; top: .7rem; background: var(--ds-gold-500); color: var(--ds-navy-900); }

/* ---- body ---- */
.feature-body {
  display: flex; flex-direction: column; gap: .45rem;
  padding: .85rem 1rem 1rem; flex: 1 1 auto;
}
.feature-title {
  font-weight: 700; color: var(--ds-navy-800);
  line-height: 1.35; font-size: .98rem;
}
.feature-card:hover .feature-title { color: var(--ds-primary); }
.feature-sub { font-size: .85rem; line-height: 1.5; color: var(--ds-muted); }
.feature-meta {
  font-size: .78rem; color: var(--ds-muted);
  display: flex; align-items: center; gap: .4rem; flex-wrap: wrap; margin-top: auto;
}
.feature-meta .dot { width: 3px; height: 3px; border-radius: 50%; background: currentColor; opacity: .5; }
.feature-cta { margin-top: auto; font-size: .84rem; }

@media (max-width: 767.98px) {
  .feature-cover { aspect-ratio: 16 / 8; }
  .feature-body  { padding: .75rem .85rem .9rem; }
  .rank-chip     { width: 34px; height: 34px; font-size: .9rem; border-radius: 10px; }
}


/* ---------------------------------------------------------------------------
   Hero rail cards on a phone

   These are house promos: a headline, a line of copy, a button, and a pale
   illustration. Three earlier attempts each traded one fault for another —
   `cover` cropped the artwork, `contain` left a seam where the image stopped
   and the card's white background began, and shrinking the copy clipped the
   button.

   What actually works is to stop treating the illustration as a picture beside
   the text and treat it as the card's own background: it covers the whole
   card, anchored right so the subject stays in view, and a light wash fades it
   out under the copy. No seam, no crop, and the text sits on a clean ground.
--------------------------------------------------------------------------- */
@media (max-width: 575px) {
  .promo-zone--hero_side .promo-slide { position: relative; overflow: hidden; }

  .promo-zone--hero_side .promo-media {
    position: absolute; inset: 0;
    width: 100%; height: 100%;
    object-fit: cover; object-position: right center;
  }

  /* The wash. Opaque under the words, clear over the artwork. */
  .promo-zone--hero_side .promo-copy::before {
    content: ''; position: absolute; inset: 0; z-index: -1;
    background: linear-gradient(100deg,
                #fff 0%, rgba(255, 255, 255, .94) 42%,
                rgba(255, 255, 255, .55) 66%, rgba(255, 255, 255, 0) 88%);
  }
  .promo-zone--hero_side .promo-copy {
    position: relative; inset: auto; isolation: isolate;
    padding: .85rem 30% .85rem 1rem; gap: .28rem;
  }

  /* The scrim element is for photographic creatives — a dark wash over a pale
     illustration only makes it muddy. */
  .promo-zone--hero_side .promo-scrim { display: none; }

  .promo-zone--hero_side .promo-title {
    font-size: .97rem; line-height: 1.25; color: var(--ds-navy-800); text-wrap: balance;
  }
  .promo-zone--hero_side .promo-sub   { font-size: .79rem; color: var(--ds-muted); }
  .promo-zone--hero_side .promo-cta   { font-size: .77rem; padding: .36rem .85rem; }
}
