/* modou dsp — shared layout & components */

/* ── Header ─────────────────────────────────────────────────────────── */
.site-header {
  position: sticky;
  top: 0;
  z-index: 100;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-md);
  padding: var(--space-sm) var(--gutter);
  background: color-mix(in srgb, var(--bg-obsidian) 82%, transparent);
  backdrop-filter: blur(16px);
  border-bottom: 1px solid var(--border-overlay);
}

/* Covers both branches: our fallback <a class="logo"> and WordPress's own
   <a class="custom-logo-link"> from the Customizer.

   width:auto alone is not enough. The global `img { max-width: 100% }`
   clamps the width on a cramped mobile header while the fixed height
   stays put, which stretches the mark. max-width:none + explicit height
   keeps the ratio at every width; the size itself is a Customizer
   setting (Appearance → Customize → Site Identity → Logo size). */
.site-header .logo img,
.site-header .custom-logo-link img {
  height: var(--logo-h, 26px);
  width: auto;
  max-width: none;
  object-fit: contain;
}
.site-header .custom-logo-link { display: flex; align-items: center; }

@media (max-width: 860px) {
  .site-header .logo img,
  .site-header .custom-logo-link img { height: var(--logo-h-mobile, 22px); }
}

.site-nav { display: flex; gap: var(--space-lg); align-items: center; }

/* The nav is a <ul>, so without this the list is the single flex item and
   every link stacks vertically — which is exactly what the header did the
   day it stopped printing bare <a> elements. */
.site-nav ul {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  gap: var(--space-lg);
  align-items: center;
}

.site-nav li { margin: 0; }

/* ── Primary nav drop-downs ───────────────────────────────────────────
   Sub-menus were being thrown away before they reached the markup
   (wp_nav_menu depth was 1), so there was never any drop-down CSS to go
   with them. Both halves are here now.

   Opened on hover *and* on focus-within, so the keyboard reaches it too —
   hover alone leaves the sub-menu unreachable without a mouse. */
.site-nav .menu-item-has-children {
  position: relative;
}

/* The caret marks which items have more under them. Drawn in CSS rather
   than added to the markup, because the markup is WordPress's. */
.site-nav .menu-item-has-children > a::after {
  content: "";
  display: inline-block;
  width: 0.4em;
  height: 0.4em;
  margin-left: 0.45em;
  border-right: 1.5px solid currentColor;
  border-bottom: 1.5px solid currentColor;
  transform: translateY(-0.15em) rotate(45deg);
  transition: transform var(--duration-fast) var(--ease-out-expo);
}

/* Top-level items stretch to the full header height so a panel anchored
   at top:100% starts exactly at the header's lower edge. Offsetting by a
   fixed number instead would have to guess at the header's padding, and
   the link is shorter than the tallest item in the bar anyway. The link
   stays vertically centred inside the stretched item. */
.site-header .site-nav,
.site-header .site-nav > ul { align-self: stretch; }

/* Only the top-level row stretches. The shared `.site-nav ul` rule above
   centres its children, which is right for a drop-down panel but would
   keep these items at text height. */
.site-header .site-nav > ul { align-items: stretch; }

.site-nav > ul > li {
  display: flex;
  align-items: center;
}

/* The item now ends at the header's content box, so the distance left to
   the header's lower edge is exactly its padding plus its border — a value
   the header already declares, rather than a number measured off a
   screenshot that would drift the moment the spacing scale changes. */
.site-nav > ul > .menu-item-has-children::after {
  content: "";
  position: absolute;
  top: 100%;
  left: 0;
  right: 0;
  height: calc(var(--space-sm) + 1px);
}

.site-nav .sub-menu {
  position: absolute;
  /* Flush with the header's lower border instead of cutting across it. */
  top: calc(100% + var(--space-sm) + 1px);
  left: 0;
  z-index: 120;
  min-width: 200px;
  margin: 0;
  /* A gap between the trigger and the panel would close the menu as the
     pointer crosses it; the padding keeps the hover target continuous. */
  padding: var(--space-xs) 0;
  display: block;
  flex-direction: column;
  align-items: stretch;
  gap: 0;
  background: var(--bg-charcoal);
  border: 1px solid var(--border-overlay);
  border-radius: var(--radius-card);
  box-shadow: var(--shadow-lg, 0 20px 40px -20px rgba(0, 0, 0, 0.8));
  opacity: 0;
  visibility: hidden;
  transform: translateY(-4px);
  transition: opacity var(--duration-fast) var(--ease-out-expo),
              transform var(--duration-fast) var(--ease-out-expo),
              visibility var(--duration-fast);
}

.site-nav .menu-item-has-children:hover > .sub-menu,
.site-nav .menu-item-has-children:focus-within > .sub-menu {
  opacity: 1;
  visibility: visible;
  transform: translateY(0);
}

.site-nav .menu-item-has-children:hover > a::after,
.site-nav .menu-item-has-children:focus-within > a::after {
  transform: translateY(0.05em) rotate(-135deg);
}

.site-nav .sub-menu li { width: 100%; }

.site-nav .sub-menu a {
  display: block;
  padding: 0.55rem var(--space-sm);
  font-size: var(--text-sm);
  font-weight: 500;
  letter-spacing: 0;
  white-space: nowrap;
}

.site-nav .sub-menu a:hover { color: var(--product-accent); }

.site-nav a {
  font-size: var(--text-sm);
  font-weight: 600;
  letter-spacing: 0.04em;
  color: var(--text-muted);
  transition: color var(--duration-fast) var(--ease-out-expo);
}
.site-nav a:hover,
.site-nav a[aria-current="page"] { color: var(--text-primary); }

.header-actions { display: flex; align-items: center; gap: var(--space-sm); }

.icon-btn {
  width: 38px; height: 38px;
  display: flex; align-items: center; justify-content: center;
  border-radius: 50%;
  border: 1px solid var(--border-overlay);
  color: var(--text-muted);
}
.icon-btn:hover { color: var(--text-primary); border-color: var(--text-muted); }

/* mobile nav toggle: hidden checkbox pattern, no JS required */
.nav-toggle { display: none; }
.nav-toggle-label { display: none; }

@media (max-width: 860px) {
  .site-nav,
  /* The <ul> has to stack too, or the drawer keeps the links in a row
     and they run off the side of the screen. */
  .site-nav ul {
    flex-direction: column;
    align-items: flex-start;
    gap: var(--space-md);
  }

  /* In the drawer a floating panel makes no sense — there is nothing to
     float over. Sub-menus become an indented list that is always open. */
  .site-nav .sub-menu {
    position: static;
    opacity: 1;
    visibility: visible;
    transform: none;
    min-width: 0;
    margin: var(--space-xs) 0 0 var(--space-sm);
    padding: 0 0 0 var(--space-sm);
    border: none;
    border-left: 1px solid var(--border-overlay);
    border-radius: 0;
    background: transparent;
    box-shadow: none;
  }

  .site-nav .menu-item-has-children > a::after { display: none; }

  /* Undo the header-bar geometry. In the drawer there is no header edge to
     align to: the item has to stack its link above its sub-list, and the
     hover bridge would only be an invisible 17px overlay sitting on top of
     the links, swallowing taps. */
  .site-header .site-nav,
  .site-header .site-nav > ul { align-self: auto; }
  .site-header .site-nav > ul { align-items: flex-start; }

  .site-nav > ul > li {
    display: block;
    align-items: normal;
  }

  .site-nav > ul > .menu-item-has-children::after { display: none; }

  /* The drawer hangs off the header, and is positioned `absolute` rather
     than `fixed` on purpose.

     `position: fixed` does not resolve against the viewport here: the
     header sets `backdrop-filter`, and a backdrop-filter (like a filter or
     a transform) makes an element the containing block for its fixed
     descendants. So `inset: 64px 0 0 0` was being measured against a ~70px
     tall header instead of the screen — the panel collapsed to a few
     pixels, its background with it, and the links spilled out over the
     page with nothing behind them. That is the "transparent menu" on a
     phone.

     Anchored at `top: 100%` it sits on the header's lower edge the same
     way the desktop drop-down does, and the percentage max-height
     resolves against that same header box, so `100dvh - 100%` is exactly
     the screen minus the header — whatever the header's height turns out
     to be. */
  .site-nav {
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    max-height: calc(100vh - 100%);
    max-height: calc(100dvh - 100%);
    overflow-y: auto;
    padding: var(--gutter);
    background: var(--bg-obsidian);
    border-bottom: 1px solid var(--border-overlay);
    transform: translateY(-8px);
    opacity: 0;
    pointer-events: none;
    transition: opacity var(--duration-normal) var(--ease-out-expo),
                transform var(--duration-normal) var(--ease-out-expo);
  }
  .nav-toggle:checked ~ .site-nav {
    opacity: 1; transform: translateY(0); pointer-events: auto;
  }
  /* Sits directly left of the account and cart buttons, so it takes their
     shape too — three round controls read as one group, where a square one
     among two circles reads as something else that happens to be nearby. */
  .nav-toggle-label {
    display: flex; width: 38px; height: 38px;
    align-items: center; justify-content: center;
    border: 1px solid var(--border-overlay); border-radius: 50%;
    color: var(--text-muted);
    cursor: pointer;
    transition: color var(--duration-fast) var(--ease-out-expo),
                border-color var(--duration-fast) var(--ease-out-expo);
  }
  .nav-toggle-label:hover,
  .nav-toggle:checked ~ .header-actions .nav-toggle-label {
    color: var(--text-primary); border-color: var(--text-muted);
  }
}

/* ── Breadcrumb (shared: shop, PDP, cart, account) ─────────────────── */
.breadcrumb {
  max-width: 1180px; margin: 0 auto; padding: var(--space-sm) var(--gutter) 0;
  font-size: var(--text-xs); color: var(--text-faint);
}
.breadcrumb a { color: var(--text-muted); }
.breadcrumb a:hover { color: var(--text-primary); }

/* ── Glass card ─────────────────────────────────────────────────────── */
.glass-card {
  background: color-mix(in srgb, var(--bg-charcoal) 88%, transparent);
  border: 1px solid var(--border-overlay);
  border-radius: var(--radius-card);
  backdrop-filter: blur(20px);
}

.glass-panel {
  background: linear-gradient(160deg,
    color-mix(in srgb, var(--product-accent) 10%, var(--bg-charcoal)) 0%,
    var(--bg-charcoal) 55%);
  border: 1px solid color-mix(in srgb, var(--product-accent) 30%, var(--border-overlay));
  border-radius: var(--radius-card);
  box-shadow: 0 40px 80px -40px color-mix(in srgb, var(--product-accent) 35%, transparent);
}

/* ── Buttons ────────────────────────────────────────────────────────── */
.btn {
  display: inline-flex; align-items: center; gap: 0.5rem;
  padding: 0.85rem 1.6rem;
  border-radius: 10px;
  font-weight: 600;
  font-size: var(--text-sm);
  border: 1px solid transparent;
  transition: transform var(--duration-fast) var(--ease-out-expo),
              background var(--duration-fast) var(--ease-out-expo),
              border-color var(--duration-fast) var(--ease-out-expo);
}
.btn:hover { transform: translateY(-1px); }

.btn-primary {
  background: var(--product-accent);
  color: var(--bg-obsidian);
}
.btn-primary:hover { background: color-mix(in srgb, var(--product-accent) 85%, white); }

.btn-secondary {
  background: transparent;
  border-color: var(--border-overlay);
  color: var(--text-primary);
}
.btn-secondary:hover { border-color: var(--product-accent); color: var(--product-accent); }

/* ── Section rhythm ─────────────────────────────────────────────────── */
.section { padding: var(--space-section) var(--gutter); }
.section-inner { max-width: 1180px; margin-inline: auto; }

/* ── Generic page content (page.php) ──────────────────────────────────
   Editor-authored pages (Technology/Support/About) get the same 1180px
   content width as every other page on the site — this used to be capped
   at 820px "for readability," which quietly broke every full-width
   embed a page might contain (e.g. the existing {product}-manual/ pages,
   which iframe a complete standalone manual document). Embedded iframes
   always fill 100% of whatever width they're given, full stop — an
   iframe with no explicit width falls back to the browser default
   (~300px) and nothing about the surrounding container fixes that on
   its own. */
.entry-content-wrap iframe { width: 100%; }
.entry-content-wrap .video-container { position: relative; width: 100%; }
.eyebrow {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  font-weight: 600;
  letter-spacing: 0.12em;
  color: var(--product-accent);
  text-transform: uppercase;
}

/* ── Footer ─────────────────────────────────────────────────────────── */
.site-footer {
  border-top: 1px solid var(--border-overlay);
  padding: var(--space-xl) var(--gutter) var(--space-lg);
}
.footer-brand {
  max-width: 1180px;
  margin-inline: auto;
}
.footer-bottom {
  max-width: 1180px; margin: var(--space-lg) auto 0;
  padding-top: var(--space-md);
  border-top: 1px solid var(--border-overlay);
  display: flex; justify-content: space-between; flex-wrap: wrap; gap: var(--space-sm);
  color: var(--text-faint); font-size: var(--text-xs);
}


/* ── Technology page (page-technology.php) ──────────────────────────── */
.tech-hero .section-head { margin-bottom: var(--space-sm); }

.tech-stages { list-style: none; margin: var(--space-lg) 0 0; padding: 0; display: grid; gap: 0; }
.tech-stages li {
  display: grid; grid-template-columns: 4rem 1fr; gap: var(--space-md);
  padding: var(--space-md) 0; border-top: 1px solid var(--border-overlay);
}
.tech-stages li:last-child { border-bottom: 1px solid var(--border-overlay); }
.tech-stages .code { color: var(--accent-cyan); font-size: var(--text-sm); }
.tech-stages h3 { font-size: var(--text-lg); margin: 0 0 0.3rem; letter-spacing: -0.01em; }
.tech-stages p { color: var(--text-muted); margin: 0; max-width: 62ch; }
.tech-note { margin: var(--space-lg) 0 0; font-size: var(--text-lg); max-width: 52ch; }

.tech-pillars {
  list-style: none; margin: var(--space-lg) 0 0; padding: 0;
  display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: var(--space-sm);
}
.tech-pillars li { padding: var(--space-md); border-radius: var(--radius-card); border: 1px solid var(--border-overlay); background: var(--bg-charcoal); }
.tech-pillars h3 { font-size: var(--text-base); margin: 0 0 0.4rem; }
.tech-pillars p { font-size: var(--text-sm); color: var(--text-muted); margin: 0; }

.tech-engine { padding: var(--space-xl); }
.tech-engine h2 { font-size: var(--text-xl); margin: 0.4rem 0 var(--space-sm); }
.tech-engine p { color: var(--text-muted); max-width: 70ch; margin: 0 0 var(--space-sm); }
/* The scope caveat is the load-bearing sentence on this page: it stops
   CyanoCore reading as a claim over products it has nothing to do with. */
.tech-engine .tech-scope {
  color: var(--text-faint); font-size: var(--text-sm);
  padding-left: var(--space-sm); border-left: 2px solid var(--border-overlay); margin: 0;
}

@media (max-width: 620px) {
  .tech-stages li { grid-template-columns: 1fr; gap: 0.3rem; }
}

/* ── Download / trial / licence terms ──────────────────────────────────
   One component, three surfaces: the Shop grid, every product page and
   the manuals (inc/template-tags.php → modou_license_note). Written as a
   definition list rather than a paragraph because these are three
   separate answers people scan for, not prose they read. */

.license-note {
  border: 1px solid var(--border-overlay);
  border-radius: var(--radius-card);
  background: color-mix(in srgb, var(--bg-charcoal) 70%, transparent);
  padding: var(--space-md);
  margin: var(--space-md) 0;
}

.license-note-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 0.7rem;
}

.license-note-list li {
  display: grid;
  grid-template-columns: 8.5rem 1fr;
  gap: 0.9rem;
  align-items: baseline;
}

.license-note-key {
  font-size: var(--text-xs);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--accent-mint);
}

.license-note-val {
  font-size: var(--text-sm);
  color: var(--text-muted);
  line-height: 1.55;
}

/* Shop: sits above the filter bar, so it stays a single quiet line of
   reassurance rather than a block that pushes the grid down. */
.license-note.is-compact { padding: 0.85rem var(--space-md); }
.license-note.is-compact .license-note-list {
  grid-auto-flow: column;
  grid-auto-columns: 1fr;
  gap: var(--space-md);
}
.license-note.is-compact .license-note-list li {
  grid-template-columns: 1fr;
  gap: 0.2rem;
}

@media (max-width: 860px) {
  .license-note-list li { grid-template-columns: 1fr; gap: 0.2rem; }
  .license-note.is-compact .license-note-list {
    grid-auto-flow: row;
    gap: 0.7rem;
  }
}

/* ── Embedded manuals ──────────────────────────────────────────────────
   inc/manual-embed.php frames the static manual document; assets/js/
   manual-embed.js reads its height (same origin) and sets it on the
   wrapper, so the page scrolls once instead of trapping a second
   scrollbar inside the frame. */

.manual-embed {
  position: relative;
  width: 100%;
  /* Fallback only — the script replaces this with the document's real
     height. Tall enough that a JS failure still shows a usable manual
     rather than a letterbox. */
  height: 150vh;
  margin: var(--space-lg) 0 var(--space-md);
  border: 1px solid var(--border-overlay);
  border-radius: var(--radius-card);
  overflow: hidden;
  background: var(--bg-charcoal);
}

.manual-embed iframe {
  display: block;
  width: 100%;
  height: 100%;
  border: 0;
}

/* `is-fitted` is a state hook only — the measured height is written
   inline by the script, so any height declared here would lose to it
   anyway. It marks that the frame is no longer at its guessed size, and
   drops the placeholder background now that real content is behind it. */
.manual-embed.is-fitted { background: transparent; }

.manual-openlink { font-size: var(--text-sm); }
.manual-openlink a { color: var(--accent-cyan); }

/* Editors only — see modou_render_manual_embed(). */
.manual-missing {
  border: 1px solid var(--accent-peak);
  border-left-width: 3px;
  border-radius: var(--radius-card);
  padding: var(--space-md);
  margin: var(--space-lg) 0;
  font-size: var(--text-sm);
  color: var(--text-muted);
}
.manual-missing code { color: var(--text-primary); word-break: break-all; }

/* ── Header language switcher ──────────────────────────────────────────
   inc/language.php. Native <details> so it works without script — this
   is the control someone uses precisely because they cannot read the
   page, and it must not depend on a JS bundle having loaded. */

.modou-lang-menu { position: relative; }

.modou-lang-menu > summary {
  display: inline-flex; align-items: center; gap: 4px;
  padding: 6px 9px;
  border: 1px solid var(--border-overlay);
  border-radius: 999px;
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.06em;
  color: var(--text-muted);
  cursor: pointer;
  user-select: none;
  list-style: none;                 /* Firefox */
  transition: color .14s ease, border-color .14s ease;
}
.modou-lang-menu > summary::-webkit-details-marker { display: none; }
.modou-lang-menu > summary:hover { color: var(--text-primary); border-color: #414a56; }
.modou-lang-menu > summary:focus-visible { outline: 2px solid var(--accent-cyan); outline-offset: 2px; }
.modou-lang-menu[open] > summary { color: var(--text-primary); border-color: #414a56; }
.modou-lang-menu[open] .chev { transform: rotate(180deg); }
.modou-lang-menu .chev { opacity: .7; transition: transform .18s var(--ease-out-expo); }

.modou-lang-list {
  position: absolute;
  top: calc(100% + 8px);
  /* Right-aligned: this sits near the end of the header row, and a
     left-aligned panel would hang off the viewport on a phone. */
  right: 0;
  z-index: 60;
  min-width: 148px;
  display: flex; flex-direction: column;
  padding: 6px;
  border: 1px solid var(--border-overlay);
  border-radius: 12px;
  background: var(--bg-charcoal);
  box-shadow: 0 18px 40px -22px rgba(0,0,0,.9);
}
.modou-lang-list .modou-lang {
  padding: 7px 10px;
  border-radius: 8px;
  font-size: var(--text-sm);
  color: var(--text-muted);
  white-space: nowrap;
  transition: color .12s ease, background-color .12s ease;
}
.modou-lang-list .modou-lang:hover { color: var(--text-primary); background: rgba(255,255,255,.05); }
.modou-lang-list .modou-lang.is-active { color: var(--accent-mint); }

@media (prefers-reduced-motion: reduce) {
  .modou-lang-menu > summary,
  .modou-lang-menu .chev,
  .modou-lang-list .modou-lang { transition: none; }
}

/* ── Header at phone width ─────────────────────────────────────────────
   Measured, not guessed. With language and currency both in the row the
   header needed 478px of content inside a 375px viewport — 103px over.
   Whitespace was most of it: 80px of side padding plus 96px of gaps.

   The controls themselves are already as small as they should get (the
   currency drops to a single pill above, the language collapses to a
   two-letter badge), so the space comes from the padding, the gaps and
   the icon buttons. That lands at ~352px with room to spare.

   The logo is deliberately NOT shrunk here: its height is a Customizer
   setting, and quietly overriding an administrator's choice to win a few
   pixels is the wrong trade. */
@media (max-width: 560px) {
  /* The header keeps the page gutter rather than a tighter value of its
     own. Shaving a couple of pixels here bought almost nothing and left
     the logo sitting left of every heading below it, which reads as a
     misalignment rather than as extra room. The width the controls need
     comes from the smaller gap and icons below. */
  .site-header { gap: 10px; }
  .header-actions { gap: 6px; }
  .icon-btn { width: 34px; height: 34px; }
  .nav-toggle-label { width: 34px; height: 34px; }
  .modou-lang-menu > summary { padding: 6px 7px; }
  /* The panel is wider than the badge that opens it, so keep it inside
     the viewport rather than letting it hang off the right edge. */
  .modou-lang-list { min-width: 140px; max-width: calc(100vw - 28px); }
}

/* Editor-content template ------------------------------------------------
   Pages switched to "Editor content (no theme layout)" render whatever the
   editor produced and nothing else.

   Elementor brings its own full-width sections and its own spacing, so it
   is left alone — anything it wraps in .elementor keeps the full viewport.
   Plain editor blocks have no container of their own, and without this
   they sit flush against both screen edges. */
.modou-editor-canvas > :not(.elementor) {
  max-width: 1180px;
  margin-inline: auto;
  padding-inline: var(--space-sm, 1rem);
}

.modou-editor-canvas {
  padding-block: var(--space-md, 3rem);
}

/* ── Footer, now brand + legal only ───────────────────────────────────── */
.footer-tagline {
  color: var(--text-faint);
  font-size: var(--text-sm);
  margin-top: var(--space-sm);
  max-width: 42ch;
}
