/* Video library — the shared clip library: its tab set, its grid and its card.
 *
 * One sheet styles every place a clip is printed: the Videos page, which reads
 * the library one category at a time, and a product, solution or support page,
 * which prints the handful of clips that belong to it as one plain grid. Both
 * build their cards through components/video-card.php, so the card is stated
 * once here rather than once per page.
 *
 * The behaviour lives beside this file and is not repeated in it:
 * assets/js/tabs.js switches the tab set — the tabs contract, written as the
 * site's own script because the fixed-version behaviour library's build cannot
 * be published through this site's push path — and assets/js/video-embed.js
 * builds the player inside a card that has been pressed. Neither of them states
 * a colour: what a card, a tab and a panel look like is decided here.
 *
 * Every value comes from assets/css/tokens.css. The two translucent surfaces —
 * the scrim under the label over the picture and the circle around the play
 * triangle — are mixed from a token with color-mix() rather than written as
 * colours of their own, so a change in the token file reaches them too. A
 * browser that cannot mix colours takes the token at full strength from the
 * line above the mix, and the label stays readable over any picture either way.
 *
 * Not here: .section, .panel, .lift, .btn and .panel__title. The card keeps the
 * shared .panel and the shared .lift for its body, and this sheet adds its
 * frame, its play control, the label over the picture and the lines and chips
 * under it. Nothing here reaches outside the library's own names —
 * video-tabs*, video-grid, video-group*, video-card*, video-empty — so no other
 * page's class is restyled from this file.
 */

/* --------------------------------------------------------------- The tabs --
   The tab bar is one row of buttons that keeps its order and swipes sideways
   rather than wrapping: the categories read as a sequence, and a bar that
   wrapped would put the last one under the first with nothing to show it had
   moved. The scrollbar itself is hidden — the next button showing at the edge
   is the cue that there is more, and a scrollbar under a row of tabs is chrome
   the page does not need. The list is padded above and below so a button's
   focus ring is drawn inside the scrolling box instead of being clipped by it. */
.video-tabs__list{display:flex;gap:var(--space-1);margin:0 0 var(--space-4);padding:var(--space-1) 0;overflow-x:auto;scroll-snap-type:x proximity;scrollbar-width:none}
.video-tabs__list::-webkit-scrollbar{display:none}
.video-tabs__list > button{flex:none;scroll-snap-align:start;font:inherit;font-size:14px;font-weight:600;line-height:1.2;white-space:nowrap;padding:var(--space-1) var(--space-2);border:1px solid var(--color-line);border-radius:var(--radius-sm);background:var(--color-surface);color:var(--color-heading);cursor:pointer;transition:background var(--transition-fast),border-color var(--transition-fast),color var(--transition-fast)}
.video-tabs__list > button:hover{background:var(--color-pale);border-color:var(--color-accent);color:var(--color-accent)}
/* Which button is the open one: the state assets/js/tabs.js writes on the tab
   itself, so the stylesheet and the script can never disagree about it. */
.video-tabs__list > button[aria-selected="true"]{background:var(--color-navy);border-color:var(--color-navy);color:var(--color-surface)}
.video-tabs__list > button[aria-selected="true"]:hover{background:var(--color-navy);border-color:var(--color-navy);color:var(--color-surface)}
/* The focus ring is stated for these buttons as well as inherited from the
   site's own rule: the row scrolls, and a ring drawn at the shared offset would
   be clipped by the box that scrolls. */
.video-tabs__list > button:focus-visible{outline:2px solid var(--color-focus);outline-offset:2px}

/* ------------------------------------------------------------- The panels --
   A panel holds its own heading, the term's own line where the site wrote one,
   and the grids of the clips filed under it. No display value is set on a
   panel: the panel that is not showing carries the hidden attribute from
   assets/js/tabs.js, and assets/css/tabs.css is the rule that makes it win. */
.video-tabs__panel > h3{margin:0 0 var(--space-2)}

/* ------------------------------------------------------------- The groups --
   A category that holds sub-categories prints one group per sub-category inside
   its panel, and a library whose clips fall into a single category prints one
   group on its own. The space above a group is what separates two grids; the
   first thing in a panel takes no space from here, because the panel's heading
   already carries it. */
.video-group__title{margin:0 0 var(--space-3)}
h4.video-group__title{font-size:17px;font-weight:600}
.video-tabs__lede,
.video-group__lede{margin:0 0 var(--space-3);max-width:70ch;font-size:15px;color:var(--color-muted)}
.video-group + .video-group,
.video-grid + .video-group,
h3 + .video-group,
.video-tabs__lede + .video-group,
.video-group__lede + .video-group{margin-top:var(--space-5)}

/* --------------------------------------------------------------- The grid --
   Three cards across on a desktop, two from 1024px down, one from 700px down.
   The counts are stated rather than left to an auto-fit rule, because a library
   reads as a shelf: the same three columns on every desktop screen, not four on
   a wide one and two on a narrow laptop. 1024px is where a third card would
   fall under about 300px, and both its label over the picture and its title
   would wrap to two lines there; 700px is where a pair leaves each card about
   330px, and two cards of that width read as one row of small print on a phone
   rather than as pictures to press. */
.video-grid{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:var(--space-4)}

/* --------------------------------------------------------------- The card --
   The card is the shared .panel with the shared .lift, so its ground, its
   border and the way it lifts under the pointer are the site's own; this sheet
   adds the frame, the play control, the label over the picture and the lines
   under it. The frame is 16:9 whether or not a clip is playing: the player that
   assets/js/video-embed.js builds takes the picture's own box, so the page
   never moves when a visitor presses a card.

   The markup these rules are written for, printed by components/video-card.php:
   the names below are the contract, and assets/js/video-embed.js reads two of
   them — [data-video-play] carries the id and .video-card__frame is the box the
   player replaces the picture inside — so neither of those may move.

     <article class="panel lift video-card">
       <div class="video-card__frame">
         <a class="video-card__play" href="…" data-video-play="…" data-video-title="…">
           <img class="video-card__thumb" src="…" alt="" width="480" height="360" loading="lazy" decoding="async">
           <p class="video-card__label" aria-hidden="true">
             <span class="video-card__mark">HOBER</span>
             <span class="video-card__label-text">Tank sensor setup</span>
           </p>
           <span class="video-card__glyph" aria-hidden="true"></span>
         </a>
       </div>
       <h4 class="video-card__title">…</h4>
       <p class="video-card__meta">12:38 · HOBER on YouTube</p>
       <p class="video-card__note">…</p>
       <ul class="video-card__tags"><li>…</li></ul>
     </article> */
.video-card__frame{position:relative;overflow:hidden;aspect-ratio:16/9;border-radius:var(--radius-md);background:var(--color-pale)}

/* The picture covers the frame whatever shape it arrives in: the thumbnail
   YouTube publishes is 4:3, so covering a 16:9 frame crops its bars rather than
   leaving them letterboxed inside it. */
.video-card__thumb{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;transition:opacity var(--transition-fast)}

/* The whole frame is the control, and it says so with the pointer. Its focus
   ring is drawn inside the frame rather than around it, because the frame clips
   whatever falls outside itself. */
.video-card__play{position:relative;display:block;height:100%;cursor:pointer}
.video-card__play:focus-visible{outline:2px solid var(--color-focus);outline-offset:-2px;border-radius:var(--radius-md)}

/* The play control: one circle in the site's navy with a triangle drawn from
   borders, centred over the picture. It is drawn, never a text glyph and never
   a background image, so it stays crisp at any size and costs no request. */
.video-card__glyph{position:absolute;top:50%;left:50%;display:flex;align-items:center;justify-content:center;width:clamp(48px,16%,68px);aspect-ratio:1/1;border:1px solid var(--color-surface);border-color:color-mix(in srgb,var(--color-surface) 72%,transparent);border-radius:50%;background:var(--color-navy);background:color-mix(in srgb,var(--color-navy) 62%,transparent);transform:translate(-50%,-50%);transition:background var(--transition-fast),border-color var(--transition-fast),transform var(--transition-fast)}
.video-card__glyph::before{content:"";display:block;width:0;height:0;margin-left:4px;border-style:solid;border-width:10px 0 10px 16px;border-color:transparent transparent transparent var(--color-surface)}

/* Feedback: the picture dims and the circle takes the action blue, under the
   pointer and under the keyboard alike. */
.video-card__play:hover .video-card__thumb{opacity:.82}
.video-card__play:hover .video-card__glyph,
.video-card__play:focus-visible .video-card__glyph{background:var(--color-accent);border-color:var(--color-surface)}
.video-card__play:hover .video-card__glyph{transform:translate(-50%,-50%) scale(1.06)}

/* The label over the picture: the maker's mark and the record's own three to
   six words. It is read over whatever opening frame the clip happens to have, so
   it is never bare text — a translucent navy scrim carries it, with the wordmark
   in the sun accent on top of that, so a dark or a light picture behind it
   leaves the same contrast. It sits in the link, so a visitor who presses a word
   presses the card. */
.video-card__label{position:absolute;z-index:1;bottom:var(--space-2);left:var(--space-2);display:flex;align-items:baseline;gap:var(--space-1);max-width:calc(100% - var(--space-4));margin:0;padding:var(--space-1) var(--space-2);border-radius:var(--radius-sm);background:var(--color-navy);background:color-mix(in srgb,var(--color-navy) 76%,transparent);color:var(--color-surface);font-size:12px;font-weight:600;line-height:1.4;pointer-events:none}
.video-card__mark{font-size:11px;font-weight:700;letter-spacing:.14em;text-transform:uppercase;color:var(--color-sun)}
/* The label's own words break inside the scrim rather than overflow it: a word
   is allowed to be narrower than the item, which is what lets a four-word label
   take two lines in a narrow frame. */
.video-card__label-text{min-width:0}

/* The player, once a card has been pressed: it takes the frame the picture had,
   so the card keeps its box and the page does not move. */
.video-card__embed{position:absolute;inset:0;width:100%;height:100%;border:0}

/* The lines under the frame: the clip's own title, then what it is and where it
   comes from in tabular numerals — a duration is a column of digits, and one of
   them should not shift the line under it — then the one or two lines the record
   carries about the clip, then its tags as small chips. The chips take the small
   radius token rather than a pill's own radius, so the shape of every corner in
   this file comes from the token file like its colours and its spacing do. */
.video-card__title{margin:var(--space-2) 0 var(--space-1);font-size:19px;font-weight:600;line-height:1.3;color:var(--color-heading)}
.video-card__meta{margin:0;font-size:13px;color:var(--color-muted);font-variant-numeric:tabular-nums}
.video-card__note{margin:var(--space-2) 0 0;font-size:14px;line-height:1.55;color:var(--color-muted)}
.video-card__tags{display:flex;flex-wrap:wrap;gap:var(--space-1);margin:var(--space-2) 0 0;padding:0;list-style:none}
.video-card__tags li{padding:var(--space-1) var(--space-2);border:1px solid var(--color-line);border-radius:var(--radius-sm);background:var(--color-pale);font-size:12px;font-weight:600;color:var(--color-muted)}

/* ------------------------------------------------------------ Nothing yet --
   A library that matched nothing, printed only where the caller passed a line
   for it: the shared panel block, kept to a readable measure. Where no line was
   passed, components/video-library.php prints nothing at all and leaves no empty
   box on the page. */
.video-empty{max-width:64ch}

/* ------------------------------------------------------------- Responsive --
   The row counts above, in the order a screen loses width, plus the one spacing
   a phone needs: with one card across, two groups read as one list, so the space
   between them comes down to the section's own middle step. */
@media(max-width:1024px){
  .video-grid{grid-template-columns:repeat(2,minmax(0,1fr))}
}
@media(max-width:700px){
  .video-grid{grid-template-columns:minmax(0,1fr)}
  .video-group + .video-group,
  .video-grid + .video-group,
  h3 + .video-group,
  .video-tabs__lede + .video-group,
  .video-group__lede + .video-group{margin-top:var(--space-4)}
}

/* A browser that asks for less motion gets every colour change without the
   movement: the picture keeps its opacity and the play control its size, and the
   tab buttons change colour with no transition, as everywhere else on the site. */
@media(prefers-reduced-motion:reduce){
  .video-tabs__list > button,
  .video-card__thumb,
  .video-card__glyph{transition:none}
}
