/* Meridian Timing catalog — page styles.
   Every value here comes from the "Timing Catalog" canvas; the inline styles
   and style-hover attributes of the design are expressed as real rules. */

body { margin: 0; background: var(--color-bg); }
a:hover { color: var(--color-accent-700); }

@keyframes fadeUp {
  from { opacity: 0; transform: translateY(10px); }
  to   { opacity: 1; transform: none; }
}

#app {
  min-height: 100vh;
  background: var(--color-bg);
  color: var(--color-text);
  font-family: var(--font-body);
  font-size: 15px;
  line-height: 1.55;
}

.wrap { max-width: 1360px; margin: 0 auto; }

/* ── header ─────────────────────────────────────────────────────────── */

.site-header { border-bottom: 2px solid var(--color-divider); }

.header-top {
  padding: var(--space-6);
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: var(--space-6);
  align-items: start;
}

.brand { display: block; text-decoration: none; color: var(--color-text); }
.brand-name {
  display: block;
  font-family: var(--font-heading); font-weight: 800;
  font-size: 26px; letter-spacing: -0.02em; line-height: 1;
}
.brand-accent { color: var(--color-accent); }
.brand-slogan {
  display: block; margin-top: var(--space-2);
  font-size: 13px; letter-spacing: 0.04em; text-transform: uppercase;
  color: var(--color-neutral-700);
}

.header-contact {
  display: flex; flex-direction: column; gap: 2px;
  font-size: 13px; color: var(--color-neutral-700);
  justify-self: end; text-align: right;
}
.header-phone {
  font-family: var(--font-heading); font-weight: 800;
  font-size: 15px; color: var(--color-text);
}

/* The strip is plain text apart from the two actionable lines; keep them
   looking like the rest of it rather than like default links. */
.header-contact a { color: inherit; text-decoration: none; }
.header-contact a:hover { color: var(--color-accent); }

/* ── manufacturer strip ─────────────────────────────────────────────── */

/* No heading above it, so the two rules keep it from reading as a gallery:
   the marks are muted until pointed at, and they sit between two hairlines
   that separate them from the copy above and the catalog below. */
.sec-brands {
  padding: var(--space-6);
  border-top: 2px solid var(--color-divider);
  border-bottom: 2px solid var(--color-divider);
}
.brands {
  list-style: none; margin: 0; padding: 0;
  display: flex; flex-wrap: wrap; align-items: center; justify-content: center;
  gap: var(--space-6) var(--space-8);
}
.brand { display: flex; align-items: center; }
.brand a { display: flex; align-items: center; }
.brand img {
  height: 30px; width: auto; max-width: 150px; object-fit: contain;
  display: block;
  /* Fifteen brand palettes side by side fight each other and outshout the
     catalog. Grey at rest, full colour on the one being considered. */
  filter: grayscale(1) contrast(0.9);
  opacity: 0.55;
  transition: filter 160ms ease, opacity 160ms ease;
}
.brand a:hover img,
.brand a:focus-visible img { filter: none; opacity: 1; }
.brand a:focus-visible { outline: 2px solid var(--color-accent); outline-offset: 4px; }

/* ── search suggestions ─────────────────────────────────────────────── */

/* The panel hangs off the form, so the form is the positioning context. */
form.search.has-suggest { position: relative; }

.search-suggest {
  position: absolute; z-index: 60; top: calc(100% + 6px); left: 0; right: 0;
  max-height: min(60vh, 420px); overflow-y: auto;
  /* --color-surface is a grey; the panel floats over content and needs
     to separate from it, so it takes the lightest step of the ramp. */
  background: var(--color-neutral-100);
  border: 2px solid var(--color-divider);
  box-shadow: 0 12px 28px rgb(0 0 0 / 12%);
}
.search-suggest__item {
  display: flex; gap: var(--space-3); align-items: center;
  padding: var(--space-2) var(--space-3);
  text-decoration: none; color: var(--color-text);
  border-bottom: 1px solid var(--color-divider);
}
.search-suggest__item:last-of-type { border-bottom: 0; }
.search-suggest__item img {
  width: 44px; height: 44px; object-fit: contain; flex: none;
  background: var(--color-neutral-200);
}
.search-suggest__item > span { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.search-suggest__title {
  font-weight: 600; line-height: 1.25;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.search-suggest__meta { font-size: 12px; color: var(--color-neutral-700); }
.search-suggest__item.is-active,
.search-suggest__item:hover { background: var(--color-accent-100); }
.search-suggest__more,
.search-suggest__none {
  display: block; margin: 0; padding: var(--space-3);
  font-size: 13px; letter-spacing: 0.04em; text-transform: uppercase;
  color: var(--color-accent); text-decoration: none;
  border-top: 2px solid var(--color-divider);
}
.search-suggest__none { color: var(--color-neutral-700); text-transform: none; letter-spacing: 0; }

.header-bar { border-top: 2px solid var(--color-divider); }
.header-bar-inner {
  padding: var(--space-3) var(--space-6);
  display: flex; gap: var(--space-4); align-items: center; flex-wrap: wrap;
}

/* form.search, not .search: WordPress puts a "search" class on <body> for every
   results page, so a bare .search also matched the body and turned it into a
   flex row. Its one child then shrank to its content width and sat hard left
   with the rest of a wide screen empty -- visible only after a search, which
   is exactly when the class appears. */
form.search { flex: 1 1 320px; display: flex; gap: var(--space-2); align-items: center; }
form.search svg { color: var(--color-neutral-600); flex: 0 0 auto; }
form.search .input {
  flex: 1; border: 0; background: transparent;
  font-size: 14px; padding: var(--space-2) 0; min-height: 0;
}
form.search .input:hover { border-color: transparent; }

.main-nav {
  display: flex; gap: var(--space-4); align-items: center; flex-wrap: wrap;
  font-family: var(--font-heading); font-weight: 800;
  font-size: 13px; text-transform: uppercase; letter-spacing: 0.06em;
}
.main-nav a {
  text-decoration: none; color: var(--color-text);
  display: inline-flex; align-items: center; gap: 7px;
  /* A nav item is a phrase: it wraps as a whole or not at all. The row may
     wrap between items, but "Усі дисципліни" must not split down the middle. */
  white-space: nowrap;
}
.main-nav a:hover { color: var(--color-accent); }

/* ── icons ──────────────────────────────────────────────────────────── */

/* Font Awesome paths drawn inline. They take the colour of the text they sit
   beside, so every hover and inverted state already applies to them. */
.icon { flex: 0 0 auto; }
.main-nav .icon { color: var(--color-neutral-600); }
.main-nav a:hover .icon { color: inherit; }

/* The contact strip is right-aligned, so each line is its own flex row that
   ends at the margin; the icons sit against their own text rather than in a
   column of their own. */
.header-contact span,
.header-contact a { display: flex; align-items: center; gap: 6px; justify-content: flex-end; }
.header-contact .icon { color: var(--color-neutral-600); }

.footer-col span,
.footer-col a { display: flex; align-items: center; gap: 6px; }
.footer-col .icon { color: var(--color-neutral-600); }

/* ── shared ─────────────────────────────────────────────────────────── */

main { display: block; animation: fadeUp 260ms ease both; }

.sec-hero    { padding: var(--space-8) var(--space-6) var(--space-6); }
.sec-grid    { padding: var(--space-6) var(--space-6) var(--space-8); }
.sec-top     { padding: var(--space-6) var(--space-6) 0; }
.sec-plain   { padding: var(--space-8) var(--space-6); }
.sec-tail    { padding: 0 var(--space-6) var(--space-8); }
.sec-product { padding: var(--space-6); }

.link-caps {
  font-family: var(--font-heading); font-weight: 800;
  font-size: 13px; text-transform: uppercase; letter-spacing: 0.06em;
  text-decoration: none; white-space: nowrap;
}
.back {
  font-size: 12px; text-transform: uppercase; letter-spacing: 0.06em;
  text-decoration: none;
}
.kicker {
  font-size: 11px; text-transform: uppercase; letter-spacing: 0.08em;
  color: var(--color-accent);
  font-family: var(--font-heading); font-weight: 800;
}
.note {
  font-size: 11px; text-transform: uppercase; letter-spacing: 0.08em;
  color: var(--color-neutral-600);
}
.placeholder { background: var(--color-neutral-200); }

/* ── home: pictogram grid ───────────────────────────────────────────── */

/* The "all disciplines" link that used to sit beside the heading is gone --
   the grid below now carries every discipline that has stock, and the header
   nav has the full list -- so this is only the heading's spacing. */
.hero-head { margin-bottom: var(--space-6); }
/* Full measure, sized so the sentence fills exactly two lines on a desktop.
   The size tracks the CONTAINER, not the viewport: below 1360px the wrap is
   the window less its 24px gutters, so the term is (100vw - 48px) scaled by
   the ratio that fitted at 1360. A plain vw value drifts and tips the text
   into a third line on the way down.

   48px was measured, not guessed: in Geologica at the 1312px wrap the two
   lines come to 1163 and 1228px. 50px also fits, but 52px breaks to three, so this sits two
   steps back from the cliff rather than one. The ceiling holds past 1360px
   because the wrap stops growing there; the floor is the phone size this
   heading already used, so the clamp is the only rule that sets it -- the
   narrow-screen block no longer names it a second time. */
.hero-head h1 {
  margin: 0;
  font-size: clamp(26px, calc(3.66vw - 1.76px), 48px);
  line-height: 1.12;
  /* balance, not pretty: pretty fills greedily, which suits the Ukrainian
     sentence because it happens to fill the measure anyway, but left the
     shorter English one at 1304px and 582px -- one full line and a stub. */
  text-wrap: balance;
}

/* English runs shorter than Ukrainian at the same size, so it gets its own
   ceiling, measured the same way: in Geologica 60px puts the two lines at
   1221 and 1193 of the 1312px wrap. 62px also fits and 64px breaks to three
   lines, so this too sits two steps back from the cliff. */
html[lang^="en"] .hero-head h1 {
  font-size: clamp(26px, calc(4.57vw - 2.19px), 60px);
}

/* Sized to carry every discipline that has stock, not a featured dozen:
   roughly forty cards, so the cell is narrow enough to fit ten across and
   the whole catalog fits in four rows. */
.pictos {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(124px, 1fr));
  border-top: 2px solid var(--color-divider);
  border-left: 2px solid var(--color-divider);
}
.picto {
  display: flex; flex-direction: column; justify-content: space-between;
  gap: var(--space-4); padding: var(--space-3); min-height: 104px;
  border-right: 2px solid var(--color-divider);
  border-bottom: 2px solid var(--color-divider);
  text-decoration: none; color: var(--color-text);
  transition: background 160ms ease, color 160ms ease;
}
.picto:hover { background: var(--color-accent); color: var(--color-bg); }
/* The mark is a mask filled with the card's own text colour, not an image,
   so it inverts along with everything else when the card is hovered. */
.picto-mark {
  display: block; width: 32px; height: 32px; flex: 0 0 auto;
  background: currentColor;
  -webkit-mask: var(--picto) center / contain no-repeat;
          mask: var(--picto) center / contain no-repeat;
}
/* A term whose mark still comes from the admin SVG field draws as an svg
   element rather than a mask, and must not pick up the mask background. */
svg.picto-mark { background: none; }
.picto-label {
  font-family: var(--font-heading); font-weight: 800;
  font-size: 11px; text-transform: uppercase; letter-spacing: 0.03em;
  line-height: 1.25; text-wrap: balance;
}

/* ── home: the rest of the grid ─────────────────────────────────────── */

/* The tail of the list ships in the markup and is only hidden, so it is
   still in the page for a crawler and one class reveals it. */
.picto.is-rest { display: none; }
.pictos.is-open .picto.is-rest { display: flex; }
.pictos.is-open .picto-more { display: none; }

/* The twentieth card counts what it would open instead of carrying a mark:
   at this size a number says "nineteen more" faster than any icon, and it
   needs no pictogram of its own. */
.picto-count {
  font-family: var(--font-heading); font-weight: 800;
  font-size: 24px; line-height: 32px; color: var(--color-accent);
}
.picto-more:hover .picto-count { color: inherit; }

/* ── home: venue equipment ──────────────────────────────────────────── */

/* Same cards as the disciplines, under their own heading. The marks are
   objects rather than athletes -- a stand, a scoreboard, a mat -- because
   that is what the section sells; they were chosen to hold the same weight
   as the figures beside them. */
.sec-venues { padding: 0 var(--space-6) var(--space-6); }
.sec-venues h2 {
  font-size: 13px; margin: 0 0 var(--space-4);
  text-transform: uppercase; letter-spacing: 0.06em;
  color: var(--color-neutral-700);
}

/* ── home: card grid ────────────────────────────────────────────────── */

.grid-head {
  display: flex; justify-content: space-between; align-items: baseline;
  gap: var(--space-4); flex-wrap: wrap;
  border-bottom: 2px solid var(--color-divider);
  padding-bottom: var(--space-3); margin-bottom: var(--space-6);
}
/* h1 on the search and archive pages, where this is the page's own heading,
   h2 on the front page, where it sits under the hero. Same size either way --
   the level says what the heading is, not how big it looks. */
.grid-head h1,
.grid-head h2 { font-size: 22px; margin: 0; }

.filters {
  display: flex; gap: var(--space-3); flex-wrap: wrap;
  font-size: 12px; text-transform: uppercase; letter-spacing: 0.06em;
}
.filters a { text-decoration: none; color: var(--color-neutral-700); }
.filters a:hover { color: var(--color-accent); }
.filters a[aria-current='true'] { color: var(--color-accent); }

.cards {
  display: grid; gap: var(--space-6);
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
}
.card-link {
  display: flex; flex-direction: column;
  text-decoration: none; color: var(--color-text);
  border-top: 2px solid var(--color-divider); padding-top: var(--space-3);
}
.card-link:hover { color: var(--color-accent-700); }
.card-thumb {
  aspect-ratio: 4 / 3; display: flex; align-items: flex-end;
  padding: var(--space-3); margin-bottom: var(--space-3);
}
.card-link h3 { font-size: 18px; margin: var(--space-2) 0; text-wrap: pretty; }
.card-link p { margin: 0; font-size: 14px; color: var(--color-neutral-700); text-wrap: pretty; }
.card-meta-line {
  margin-top: var(--space-3); font-size: 12px;
  color: var(--color-neutral-600); letter-spacing: 0.04em;
}
.empty { margin: var(--space-8) 0; font-size: 16px; color: var(--color-neutral-700); }

/* ── discipline page ────────────────────────────────────────────────── */

.sport-head {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: var(--space-8); padding: var(--space-6) 0;
  border-bottom: 2px solid var(--color-divider);
}
.sport-head h1 { font-size: 52px; margin: var(--space-2) 0 0; letter-spacing: -0.025em; }
.sport-head p { margin: var(--space-4) 0 0; font-size: 17px; max-width: 52ch; text-wrap: pretty; }
.subs { display: flex; flex-direction: column; gap: var(--space-2); align-self: end; }
.subs-list { display: flex; flex-wrap: wrap; gap: var(--space-2); }
.tag-sub { font-size: 12px; white-space: nowrap; }

.sec-plain h2 { font-size: 22px; margin: 0 0 var(--space-4); }
.table-link { text-decoration: none; font-family: var(--font-heading); font-weight: 800; }
.table .muted { color: var(--color-neutral-700); }

.custom {
  border-top: 2px solid var(--color-divider); padding-top: var(--space-4);
  display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: var(--space-6);
}
.custom h3 { font-size: 16px; margin: 0 0 var(--space-2); }
.custom p { margin: 0; font-size: 14px; color: var(--color-neutral-700); max-width: 44ch; text-wrap: pretty; }
.iframe-slot {
  min-height: 220px; display: flex;
  align-items: center; justify-content: flex-start; padding: var(--space-4);
}
.iframe-slot .note { font-size: 12px; }

/* ── all disciplines ────────────────────────────────────────────────── */

.sec-all h1 { font-size: 42px; margin: var(--space-4) 0 var(--space-2); }
.lede {
  margin: 0 0 var(--space-8); font-size: 15px;
  color: var(--color-neutral-700); max-width: 56ch; text-wrap: pretty;
}
.group { border-top: 2px solid var(--color-divider); padding: var(--space-4) 0 var(--space-8); }
.group h2 {
  font-size: 18px; margin: 0 0 var(--space-4);
  text-transform: uppercase; letter-spacing: 0.06em;
}
.group-list {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  gap: var(--space-2) var(--space-6);
}
.group-list a {
  font-size: 14px; text-decoration: none; color: var(--color-text); padding: 2px 0;
}
.group-list a:hover { color: var(--color-accent); }

/* ── product page ───────────────────────────────────────────────────── */

.product {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
  gap: var(--space-8); padding-top: var(--space-6);
}
.product-photo {
  aspect-ratio: 4 / 3; display: flex;
  align-items: flex-end; padding: var(--space-4);
}
.product h1 { font-size: 38px; margin: var(--space-2) 0 var(--space-4); }
.product-lede { margin: 0 0 var(--space-4); font-size: 16px; max-width: 48ch; text-wrap: pretty; }
.actions { display: flex; gap: var(--space-3); flex-wrap: wrap; margin-bottom: var(--space-6); }
.actions .btn { justify-content: flex-start; white-space: nowrap; }
.spec td:first-child { color: var(--color-neutral-700); width: 40%; }

.related-head {
  font-size: 20px; margin: 0 0 var(--space-4);
  border-bottom: 2px solid var(--color-divider); padding-bottom: var(--space-3);
}
.related {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
  gap: var(--space-6);
}
.related a {
  border-top: 2px solid var(--color-divider); padding-top: var(--space-3);
  text-decoration: none; color: var(--color-text);
}
.related a:hover { color: var(--color-accent-700); }
.related h3 { font-size: 16px; margin: var(--space-2) 0 0; }

/* ── footer ─────────────────────────────────────────────────────────── */

.site-footer { border-top: 2px solid var(--color-divider); margin-top: var(--space-8); }
.footer-inner {
  padding: var(--space-6);
  display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: var(--space-6); font-size: 13px; color: var(--color-neutral-700);
}
.footer-brand {
  display: block; font-family: var(--font-heading); font-weight: 800;
  color: var(--color-text); font-size: 15px;
}
.footer-note { display: block; margin-top: var(--space-2); }
.footer-col { display: flex; flex-direction: column; gap: 4px; }
.footer-col a { text-decoration: none; color: var(--color-neutral-700); }
.footer-col a:hover { color: var(--color-accent); }
.footer-credit {
  padding: 0 var(--space-6) var(--space-5);
  font-size: 11px; color: var(--color-neutral-600);
  display: flex; flex-wrap: wrap; gap: 2px var(--space-4);
}

/* ── narrow screens ─────────────────────────────────────────────────── */

@media (max-width: 700px) {
  .header-contact { justify-self: start; text-align: left; }

  /* On a phone the header was 351px of an 812px screen -- the first result
     started at y=506, so a search returned one visible card. The e-mail and
     the address go; both are in the footer and on the contacts page, and the
     phone, which is the one line a visitor acts on, stays and stays tappable. */
  .header-contact span:not(.header-phone) { display: none; }
  .header-top { padding: var(--space-4) var(--space-4) var(--space-3); gap: var(--space-3); }
  .header-bar-inner { padding: var(--space-2) var(--space-4); gap: var(--space-2); }

  /* The three items came to 349px of the 343px available once each grew an
     icon, so the row broke in two and the header got taller -- the one thing
     the rules above are fighting. A point off the label buys back 20px and
     keeps all three on one row with the icons intact. Dropping the icons
     here would buy more, but they were asked for; the words just do not need
     to be 13px on a phone. */
  .main-nav { gap: var(--space-3); font-size: 12px; }
  .main-nav a { gap: 5px; }

  /* Hit areas. WCAG 2.5.8 asks for 24x24 CSS px; these are text links with
     almost no vertical padding, so they measured 16 to 21. The rules grow
     the box, not the type -- every one of them already centres its own
     content, so the words stay where they were and only the tappable area
     changes. The language pair was the worst on the page: two 20px boxes
     eight pixels apart. */
  .main-nav a,
  .footer-col a,
  .footer-col span { min-height: 24px; }

  .link-caps { display: inline-flex; align-items: center; min-height: 24px; }

  /* These two are too narrow as well as too short -- "UA" is 21px wide and
     "Усі" 21px -- so they get a floor on both axes and centre inside it. */
  .lang-switch a,
  .filters a {
    display: inline-flex; align-items: center; justify-content: center;
    min-height: 24px; min-width: 24px;
  }

  /* Breadcrumbs, the header phone and the credits link sit on other pages
     and were missed by the pass above. The crumb row centres instead of
     sitting on a baseline, so the "/" separators stay level with the taller
     boxes. */
  .crumbs ol,
  .crumbs li { align-items: center; }
  .crumbs a,
  .footer-credit a { display: inline-flex; align-items: center; min-height: 24px; }
  .header-phone a { min-height: 24px; }

  /* The quote button is the one thing a visitor came to press. WCAG's 24px
     is the floor, not the target; a primary action gets the 44px that every
     phone platform asks for. */
  .actions .btn { min-height: 44px; }
  .brand-slogan { margin-top: 4px; font-size: 12px; }

  /* One row that scrolls beats four ragged rows: the strip keeps its height
     and the reader swipes it, the way a logo wall behaves on a phone. */
  .sec-brands { padding: var(--space-4) 0; }
  .brands {
    flex-wrap: nowrap; justify-content: flex-start;
    gap: var(--space-6);
    overflow-x: auto; scroll-snap-type: x proximity;
    padding: 0 var(--space-4); -webkit-overflow-scrolling: touch;
  }
  .brands::-webkit-scrollbar { height: 0; }
  /* Nothing on screen says the row continues, and a scrollbar is hidden, so
     the right edge fades out: the cut-off mark is the affordance. */
  .sec-brands {
    -webkit-mask-image: linear-gradient(to right, #000 88%, transparent 100%);
    mask-image: linear-gradient(to right, #000 88%, transparent 100%);
  }
  .brand { flex: 0 0 auto; scroll-snap-align: center; }
  .brand img { height: 26px; opacity: 0.7; }

  .sport-head h1 { font-size: 38px; }
  .sec-all h1 { font-size: 32px; }
  .product h1 { font-size: 30px; }
}

@media (prefers-reduced-motion: reduce) {
  main { animation: none; }
  .picto { transition: none; }
}
