/* ==========================================================================
   3DOptix redesign — Academy ARTICLE page-unique CSS.

   Depends on: dxr-tokens.css -> dxr-components.css -> dxr-shell.css
   Enqueued CONDITIONALLY from single-academy-post.php (handle
   'dxr-page-article', dependency 'dxr-shell'), so it ships on
   /academy-post/<slug>/ only and can never reorder the shared layer.

   Transcribed from '3DOptix Website.dc.html' lines 744-819 (line references
   below are to that file) plus README §6, which is authoritative where the two
   disagree — see §2.

   THIS FILE IS THE ARTICLE'S CHROME, NOT ITS BODY.
   The body — the client's legacy, Elementor-wrapped, editor-authored HTML — is
   styled by assets/css/dxr-prose.css and by nothing here. There is not one
   selector in this file that reaches inside .dxr-prose, and there must never
   be: the prose layer is a carefully arithmetic-checked specificity ladder
   (see its header), and a stray rule from a page stylesheet landing in the
   middle of it is exactly how 27 articles get silently unstyled. If something
   about the body needs changing, change dxr-prose.css.

   RULES FOR THIS FILE:
   - SCOPE. Every selector is scoped to .dxr-page-academy-article, the wrapper
     the template emits inside the shell's <main>. No bare element selectors,
     ever. The index screen ships as dxr-page-resources.css, written in
     parallel and both screens share component names — the page scope is what
     keeps the two files from ever having to agree.
   - No new colour. Every value resolves from the token layer; the only raw
     numbers are geometry transcribed from the prototype, and each is named in
     §0 rather than repeated as a literal below.
   - The spectrum gradient appears ZERO times in this file. The header eyebrow
     uses --dxr-spectrum-eyebrow through the shared .dxr-eyebrow-bar component;
     dxr-tokens.css §1.4 documents that five-stop gradient as a different asset
     from the seven-stop --dxr-spectrum and explicitly outside the
     two-placement rule. Site-wide budget unchanged: nav 2px + footer 3px.
   - ONE media query, at --dxr-nav-break (900px), the site's only named
     breakpoint. See §2.

   Contents
     §0  Page-local custom properties
     §1  Header band
     §2  Two-column body — the grid and its collapse
     §3  Article column: pagination, end-of-article bar, legacy tag list
     §4  Sidebar shell
     §5  Sidebar (a) — promo card
     §6  Sidebar (b) — related articles
     §7  Sidebar (c) — dark CTA card
   ========================================================================== */


/* ==========================================================================
   §0 Page-local custom properties

   Prototype values with no entry in the token layer. Declared once, used by
   name below, so a design change is a one-line edit and every literal in this
   file is traceable to a prototype line.
   ========================================================================== */
.dxr-page-academy-article{
  --dxr-art-head-top:34px;                    /* proto 747 */
  --dxr-art-head-bot:clamp(27px,3.3vw,44px);  /* proto 747 */
  --dxr-art-body-top:clamp(35px,4.1vw,56px);  /* proto 765 */
  --dxr-art-aside-w:348px;                    /* README §6 — see §2 */
  --dxr-art-sticky-top:104px;                 /* proto 795 == --dxr-nav-h (76) + 28 */
  --dxr-art-card-pad:22px;                    /* proto 804 / 813 */
  --dxr-art-radius-chip:6px;                  /* legacy tag pills, §3 */
}


/* ==========================================================================
   §1 Header band — proto 746-763

   .dxr-section supplies the hairline (--rule-b) and the container; the rhythm
   is the prototype's own, much tighter than --dxr-section-y, so it is
   overridden here. The two-class selector out-ranks .dxr-section (0,1,0)
   without !important.

   An article header is a label for what follows, not a hero: no blueprint, no
   glow, no lede. Deliberately NOT .dxr-hero.
   ========================================================================== */
.dxr-page-academy-article .dxr-acad-art__head{
  background:var(--dxr-surface);
  padding:var(--dxr-art-head-top) 0 var(--dxr-art-head-bot);
}

/* --- breadcrumb ----------------------------------------------------------
   A NEW component: nothing in dxr-components.css is a breadcrumb, and the mono
   eyebrow roles are all uppercase/tracked, which a path is not. Named with the
   plain block class (not a page-prefixed one) so that when the second screen
   ships and the pattern is confirmed, promoting these five rules into the
   shared layer is a copy-paste — but scoped to this page until then, so two
   parallel page stylesheets can each carry their own copy without colliding.

   flex-wrap is load-bearing, not defensive: the third crumb is the article
   title, and the library has titles up to 42 characters. It wraps rather than
   truncates — a truncated breadcrumb tells the reader less than a two-line one.
   ------------------------------------------------------------------------ */
.dxr-page-academy-article .dxr-crumbs{
  display:flex;
  align-items:center;
  flex-wrap:wrap;
  gap:10px;
  margin:0 0 28px;                              /* proto 748 */
  font:400 12px/1.4 var(--dxr-font-mono);       /* mono: a path is measured content */
  color:var(--dxr-text-subtle);
}
.dxr-page-academy-article .dxr-crumbs a{
  color:var(--dxr-text-subtle);
  transition:color .15s ease;
}
.dxr-page-academy-article .dxr-crumbs a:hover{color:var(--dxr-primary)}
.dxr-page-academy-article .dxr-crumbs__sep{color:var(--dxr-text-disabled)}
.dxr-page-academy-article .dxr-crumbs__current{color:var(--dxr-ink)}

/* --- title row -----------------------------------------------------------
   align-items:flex-end pins the CTA's baseline to the title's, exactly as the
   prototype does (753). flex-wrap drops the button under the title before it
   can squeeze the heading — the button is white-space:nowrap, so without the
   wrap a long title and a long label fight for the same row.
   ------------------------------------------------------------------------ */
.dxr-page-academy-article .dxr-acad-art__head-row{
  display:flex;
  align-items:flex-end;
  justify-content:space-between;
  gap:40px;
  flex-wrap:wrap;
}
.dxr-page-academy-article .dxr-acad-art__head-copy{
  min-width:0;   /* lets a long unbroken title shrink instead of overflowing */
}

/* Local deltas from the shared .dxr-eyebrow-bar (26px margin, 44px rule,
   .13em). Proto 751-753 gives 16px, 40px, .12em. Everything else inherited. */
.dxr-page-academy-article .dxr-acad-art__eyebrow{margin-bottom:16px}
.dxr-page-academy-article .dxr-acad-art__eyebrow .dxr-eyebrow-bar__rule{width:40px}
.dxr-page-academy-article .dxr-acad-art__eyebrow .dxr-eyebrow-bar__label{letter-spacing:.12em}

/* The type role is .dxr-h1--compact (shared, an exact match for proto 757 bar
   0.002em of tracking). Only the box is local — and the element may be an <h1>
   or a <p> depending on whether the stored content already carries an <h1>,
   which is why margin is declared here rather than relied on from the reset. */
.dxr-page-academy-article .dxr-acad-art__title{
  margin:0;
  overflow-wrap:break-word;
}

/* The CTA never shrinks below its label — it wraps to its own row instead. */
.dxr-page-academy-article .dxr-acad-art__cta{flex-shrink:0}


/* ==========================================================================
   §2 Two-column body — proto 765-767 + README §6

   RESOLVED CONTRADICTION. Proto 767 is
     grid-template-columns:repeat(auto-fit,minmax(min(100%,340px),1fr))
   which resolves to TWO EQUAL 1fr columns — a ~574px sidebar at container
   width. README §6 states minmax(0,1fr) body + a 348px sidebar at a 72px gap.
   The auto-fit form is a prototyping shortcut (it collapses without a media
   query, which is why the prototype reached for it); the README states the
   real intent and names the exact width. README wins.

   minmax(0,1fr) ON THE BODY COLUMN IS LOAD-BEARING. A grid track's default
   min-width is auto, i.e. its content's min-content size. The library ships
   <table style="width:700px"> (23 of them), images with width="1648", and
   iframes at width:100% with inline heights. Under `1fr` alone any one of
   those would widen the track and push the sidebar off the container. dxr-prose
   §12 scrolls the tables and §10 caps the images; this is the outer guarantee
   that makes those work.

   align-items:start is what makes the sidebar's position:sticky function at
   all — the default `stretch` gives the aside the full row height, leaving it
   nothing to slide within.
   ========================================================================== */
.dxr-page-academy-article .dxr-acad-art__body{
  background:var(--dxr-surface);
  padding:var(--dxr-art-body-top) 0 var(--dxr-section-y);   /* proto 765 */
}
.dxr-page-academy-article .dxr-acad-art__grid{
  display:grid;
  grid-template-columns:minmax(0,1fr) var(--dxr-art-aside-w);
  gap:var(--dxr-gap-col-xwide);                             /* 72px */
  align-items:start;
}
.dxr-page-academy-article .dxr-acad-art__main{min-width:0}

/* --- the collapse --------------------------------------------------------
   ONE breakpoint, at the site's only named one.

   Why 900px is the right number and not a guess: at a 901px viewport the
   gutter is 4vw ~= 36px, leaving 829px of container. Minus the 72px gap and
   the 348px sidebar the body column still holds 409px — comfortably above the
   340px floor the prototype itself chose. Below 900px the sidebar stacks under
   the article, un-sticks, and reads as an appendix; the dark CTA card (§7)
   becomes the end-of-article CTA. Do not introduce a second breakpoint.
   ------------------------------------------------------------------------ */
@media (max-width:900px){                                   /* == --dxr-nav-break */
  .dxr-page-academy-article .dxr-acad-art__grid{
    grid-template-columns:minmax(0,1fr);
    gap:40px;
  }
  .dxr-page-academy-article .dxr-acad-art__aside{
    position:static;
    top:auto;
  }
}


/* ==========================================================================
   §3 Article column — pagination, end-of-article bar, legacy tag list

   Everything between these two is .dxr-prose and belongs to dxr-prose.css.
   ========================================================================== */

/* wp_link_pages() for a multi-page article. Absent from the prototype (nothing
   in the library paginates today) and absent from the design, but the parent
   template called it and dropping the styling would leave bare, reset-stripped
   number links if an editor ever splits an article. Mono, because page numbers
   are measured content. */
.dxr-page-academy-article .dxr-acad-art__pages{
  display:flex;
  flex-wrap:wrap;
  align-items:center;
  gap:8px;
  margin-top:34px;
  font:500 13px/1 var(--dxr-font-mono);
  color:var(--dxr-body);
}
.dxr-page-academy-article .dxr-acad-art__pages a,
.dxr-page-academy-article .dxr-acad-art__pages > span{
  display:inline-flex;
  align-items:center;
  justify-content:center;
  /* 44px is the touch floor, matching the pagers on the four list pages.
     .dxr-acad-art__pages wraps, so the taller cells cannot widen the row. */
  min-width:44px;
  height:44px;
  padding:0 10px;
  border:1px solid var(--dxr-border);
  border-radius:var(--dxr-radius-md);
  background:var(--dxr-surface);
  color:inherit;
  transition:border-color .15s ease,color .15s ease;
}
.dxr-page-academy-article .dxr-acad-art__pages a:hover{
  border-color:var(--dxr-primary);
  color:var(--dxr-primary);
}
.dxr-page-academy-article .dxr-acad-art__pages > span{
  background:var(--dxr-ink);
  border-color:var(--dxr-ink);
  color:var(--dxr-on-dark);
}

/* --- end-of-article bar — proto 790-792 ---------------------------------
   Sits INSIDE <article>, after .dxr-prose and outside it. It is the whole of
   the prototype's article close: there is no full-width band on this screen.
   The header CTA and the dark sidebar card carry the conversion load.
   ------------------------------------------------------------------------ */
.dxr-page-academy-article .dxr-acad-art__foot{
  display:flex;
  align-items:center;
  justify-content:space-between;
  gap:24px;
  flex-wrap:wrap;
  margin-top:34px;
  padding-top:26px;
  border-top:1px solid var(--dxr-border);
}
.dxr-page-academy-article .dxr-acad-art__back{
  display:inline-flex;
  align-items:center;
  gap:8px;
  font:600 14px/1 var(--dxr-font-sans);
  color:var(--dxr-primary);
  transition:color .15s ease;
}
.dxr-page-academy-article .dxr-acad-art__back:hover{color:var(--dxr-primary-hover)}
/* The arrow is typographic — there is no icon set on this site. */
.dxr-page-academy-article .dxr-acad-art__meta{
  font:400 12px/1.4 var(--dxr-font-mono);       /* a date is measured content */
  color:var(--dxr-text-subtle);
}

/* Legacy tag list. Inert today — the CPT does not register post_tag — but the
   parent template emitted it, so it keeps a styled home rather than falling
   back to reset-stripped links if tags are ever switched on. */
.dxr-page-academy-article .dxr-acad-art__tags{
  display:flex;
  flex-wrap:wrap;
  align-items:center;
  gap:8px;
  margin-top:26px;
  font:400 12px/1 var(--dxr-font-mono);
  color:var(--dxr-text-subtle);
}
.dxr-page-academy-article .dxr-acad-art__tags a{
  padding:7px 12px;
  border:1px solid var(--dxr-border);
  border-radius:var(--dxr-art-radius-chip);
  font:600 12px/1 var(--dxr-font-sans);
  color:var(--dxr-body);
  transition:border-color .15s ease,color .15s ease;
}
.dxr-page-academy-article .dxr-acad-art__tags a:hover{
  border-color:var(--dxr-primary);
  color:var(--dxr-primary);
}


/* ==========================================================================
   §4 Sidebar shell — proto 795

   position:sticky, not fixed: the aside must stop scrolling when the article
   column runs out, which fixed cannot do. It needs three things to work and
   all three are here or in §2 — a sticky element, an `align-items:start` grid
   parent (§2), and no overflow:hidden anywhere on the ancestor chain (which is
   why this section is a plain .dxr-section and NOT .dxr-section--overlay).

   A sidebar taller than the viewport simply scrolls with the page; there is no
   inner scroller, because a nested scroll region inside a sticky panel is a
   trap on a trackpad. The three cards total ~560px, well under any laptop
   viewport.
   ========================================================================== */
.dxr-page-academy-article .dxr-acad-art__aside{
  position:sticky;
  top:var(--dxr-art-sticky-top);
  display:flex;
  flex-direction:column;
  gap:var(--dxr-gap-panels);                    /* 20px, proto 795 */
  min-width:0;
}


/* ==========================================================================
   §5 Sidebar (a) — promo card — proto 796-803

   The media slot is the ONE unresolved asset on this screen. It renders
   dxr_hatch() until the client supplies the image; the template swaps in a
   real <img> through the dxr_academy_promo_image filter, and the two cases
   share the same 200px slot so the card never changes height on swap.
   ========================================================================== */
.dxr-page-academy-article .dxr-acad-promo{
  border:1px solid var(--dxr-border);
  border-radius:var(--dxr-radius-panel);
  overflow:hidden;
  background:var(--dxr-surface);
}
.dxr-page-academy-article .dxr-acad-promo__media{
  height:200px;                                 /* == dxr_hatch( 'height' => 200 ) */
  overflow:hidden;
  background:var(--dxr-surface-raised);         /* shows while a real image decodes */
}
.dxr-page-academy-article .dxr-acad-promo__img{
  display:block;
  width:100%;
  height:100%;
  object-fit:cover;
}
.dxr-page-academy-article .dxr-acad-promo__body{padding:20px}
.dxr-page-academy-article .dxr-acad-promo__title{
  margin-bottom:8px;
  font:700 15px/1.35 var(--dxr-font-sans);
  color:var(--dxr-ink);
}
/* The shared .dxr-cta-link is 14px; proto 802 is 13px. Size only — the colour,
   the hover and the typographic arrow all stay with the component. */
.dxr-page-academy-article .dxr-acad-promo .dxr-cta-link{font-size:13px}


/* ==========================================================================
   §6 Sidebar (b) — related articles — proto 804-812

   The label reuses the shared .dxr-label--strip role, an exact match for proto
   805 (500 10px/1 mono, .12em, uppercase, --dxr-text-subtle); only its margin
   is local.

   The rows are real posts (see the query in single-academy-post.php) and the
   card is suppressed entirely when there are none, so this never renders as an
   empty frame or with invented titles.
   ========================================================================== */
.dxr-page-academy-article .dxr-acad-related{
  padding:var(--dxr-art-card-pad);
  border:1px solid var(--dxr-border);
  border-radius:var(--dxr-radius-panel);
  background:var(--dxr-surface);
}
.dxr-page-academy-article .dxr-acad-related__label{margin-bottom:16px}
.dxr-page-academy-article .dxr-acad-related__list{
  display:flex;
  flex-direction:column;
  gap:14px;
}
.dxr-page-academy-article .dxr-acad-related__link{
  padding-bottom:14px;
  border-bottom:1px solid var(--dxr-border-inner);
  font:600 14px/1.45 var(--dxr-font-sans);
  color:var(--dxr-ink);
  transition:color .15s ease;
}
/* Last row loses the rule and the padding — the card's own padding closes it. */
.dxr-page-academy-article .dxr-acad-related__link:last-child{
  padding-bottom:0;
  border-bottom:0;
}
.dxr-page-academy-article .dxr-acad-related__link:hover{color:var(--dxr-primary)}


/* ==========================================================================
   §7 Sidebar (c) — dark CTA card — proto 813-816

   .dxr-on-dark is on the element in the template, which is what gives the
   shared .dxr-cta-link its --dxr-cyan-light colour and white hover — proto 816
   asks for exactly #67E8F9, so the component already does it and nothing needs
   restating here.

   TWO PROTOTYPE ARTEFACTS, both handled explicitly:

   1. BORDER, ESCALATE. Proto 813 puts #E3E8EF — the LIGHT hairline — on a
      #0B1220 fill. The system's on-dark border is --dxr-border-on-dark
      (rgba(255,255,255,0.14)). Transcribed verbatim below because the reading
      that makes it deliberate is plausible: all three sidebar cards then share
      one frame and the stack reads as a set, one of which happens to be
      filled dark. If review calls it a copy-paste from the two light cards
      above it, the fix is one token:
          border-color:var(--dxr-border-on-dark);
      Flagged for sign-off rather than silently changed — this is a visible,
      client-facing difference either way.
   2. Proto 814's padding-top:8px on the title is residue from a removed
      element (it is the only card in the prototype whose first child is
      inset). Dropped.
   ========================================================================== */
.dxr-page-academy-article .dxr-acad-aside-cta{
  position:relative;
  overflow:hidden;
  padding:var(--dxr-art-card-pad);
  border:1px solid var(--dxr-border);            /* see artefact 1 above */
  border-radius:var(--dxr-radius-panel);
  background:var(--dxr-ink-deep);
}
.dxr-page-academy-article .dxr-acad-aside-cta__title{
  margin-bottom:8px;
  font:700 15px/1.4 var(--dxr-font-sans);
  color:var(--dxr-on-dark);
}
.dxr-page-academy-article .dxr-acad-aside-cta__text{
  margin:0 0 16px;
  font:400 13px/1.6 var(--dxr-font-sans);
  color:var(--dxr-on-dark-muted);                /* rgba(255,255,255,0.60), proto 815 */
}
/* Proto 816 is 13px; the shared .dxr-cta-link is 14px. Size only. */
.dxr-page-academy-article .dxr-acad-aside-cta .dxr-cta-link{font-size:13px}
