/*
Theme Name: Elevate Starter
Theme URI: https://elevate.co.il/
Author: Elevate Digital Studio
Author URI: https://elevate.co.il/
Description: Empty starter theme — an ACF flexible-content engine plus a menu/ACF-driven header & footer. Ships with one example "Content" section to copy. Drop in your own HTML and sections.
Version: 1.0.0
Text Domain: elevate-starter
*/

/* =========================================================
   Live overrides on top of assets/css/main.css.
   Put quick, per-project tweaks here; the compiled/base
   styles live in assets/css/main.css.
   ========================================================= */

/* Big Caslon only where it can actually set the words. The compiled base
   (main.css) puts the face on EVERY .section-title, but it is Latin-only and
   the titles come in both languages on the same pages — "OUR STORY" beside
   "תקנון האתר" — so neither the page's lang nor the class can decide. The
   title's own text does: theme.js (initLatinTitles) stamps .is-latin on a
   title with Latin letters and no Hebrew, and the face hangs on that. A
   Hebrew title keeps the body's AlmoniDLAAA — and that is also the no-JS
   fallback, which reads fine in both languages rather than dropping Hebrew
   into the browser's default serif. */
.section-title {
  font-family: unset;
}

/* !important because main.css sets the face on more specific selectors of its
   own (.some-section .section-title), and those would otherwise win here. */
.section-title.is-latin {
  font-family: 'Big Caslon', serif !important;
}

/* render_picture() only wraps the image in <picture> when a mobile version is
   set, and the design sizes the img/video itself. display:contents takes the
   wrapper out of the layout so the img is still a direct child of the media
   box and both cases look the same. */
picture {
  display: contents;
}

/* YouTube / Vimeo embeds — inc/media.php renders .elv-embed-wrap > .elv-embed.
   The design only styles video and img, so the embed fills its parent the same
   way an object-fit:cover video would. */
.elv-embed-wrap {
  position: relative;
  width: 100%;
  height: 100%;
  overflow: hidden;
  background-size: cover;
  background-position: center;
}

.elv-embed {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  /* 16:9 measured both ways round, so the frame always covers the box */
  width: 100vw;
  height: 56.25vw;
  min-width: 177.78vh;
  min-height: 100%;
  border: 0;
}

/* A backdrop is decoration — don't let the player steal clicks.

   The Process cards are here for a second reason: they are driven by the
   pointer entering and leaving the card (theme.js > initProcessVideos), and a
   pointer that crosses into an iframe is a pointer the page stops hearing
   about — so the mouseleave that should stop the clip never arrives. */
.page-hero .elv-embed,
.cta-section .elv-embed,
.about-vip .elv-embed,
.about-vision .elv-embed,
.process-page .elv-embed {
  pointer-events: none;
}

/* The About text block is the one embed the visitor operates: it waits for a
   press of play and shows the player's own controls (content/sections/about-text.php).
   The cover-crop above would blow the frame past the edges of the box and take
   the control bar with it, so here the player fits INSIDE the box instead —
   letterboxed rather than cropped, controls where the thumb expects them. */
.about-text__media .elv-embed {
  position: static;
  transform: none;
  width: 100%;
  height: 100%;
  min-width: 0;
  min-height: 0;
}

/* These blocks hold a video in the design; an image behaves the same. */
.cta-section__media img,
.about-vip__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* ---------------------------------------------------------------------------
   Contact form (content/sections/footer-form.php) and the job application form
   (content/sections/careers-page.php). The design has no states, so only the
   honeypot, the status line and the invalid/sending states live here.
   --------------------------------------------------------------------------- */

/* Contains the honeypot below, wherever the form is dropped. */
.elv-form {
  position: relative;
}

/* Hidden by clipping, NOT by an off-screen offset: inset-inline-start:-9999px
   pushes the field 9999px past its container, and in a Fancybox popup — which
   has nothing clipping it, unlike a `section` — that is a horizontal scrollbar
   across the whole page. Clipping takes it out of sight with no geometry. */
.elv-form__hp {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  border: 0;
  overflow: hidden;
  white-space: nowrap;
  clip: rect(0 0 0 0);
  -webkit-clip-path: inset(50%);
          clip-path: inset(50%);
}

.elv-form__message:empty {
  display: none;
}

.elv-form__message {
  margin-top: 1rem;
  font-size: 1.125rem;
  line-height: 1.4;
}

/* Sitting under the submit button, it is a flex child of the column and the
   column's own gap already spaces it — the margin on top of that would read as
   a second, wider gap. */
.elv-form .form-part > .elv-form__message {
  margin-top: 0;
}

.elv-form__message.--error {
  color: #b00020;
}

.elv-form__message.--success {
  color: #00141C;
}

.elv-form .--invalid {
  border-color: #b00020 !important;
}

/* The design lays the first column out with column-count: 2, which balances
   its items across two columns as a single flow — so anything added under a
   field (an error line) pushes the NEXT field into the other column, and a
   subject's extra inputs get dealt out between the columns instead of staying
   together. Same two columns as a grid instead, filled ROW by row, each field
   its own cell, in source order:

       [   subject    ][   project    ]
       [ …the subject's extra inputs… ]
       [ first name   ][    phone     ]
       [ last name    ][   e-mail     ]

   which is the order the old form had. The column gap matches .form-grid's, so
   the inner columns line up with the outer ones exactly as before, an error
   sits under its own field pushing nothing but its own row, and however many
   extra inputs a subject adds the rest keeps its place. */
@media (orientation: landscape), (min-width: 769px) and (orientation: portrait) {

  .elv-form .form-part.--first {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 1rem 1.5rem;
    -webkit-column-count: auto;
    -moz-column-count: auto;
    column-count: auto;
  }

  /* The margins existed only to space the multi-column flow; the gap does it. */
  .elv-form .form-part.--first .form-item {
    margin-bottom: 0;
  }

  /* No project dropdown for this subject (below): the subject takes the whole
     first row rather than sitting in half of one beside a gap. */
  .elv-form.--no-project .form-item.--topic {
    grid-column: 1 / -1;
  }

  /* The message column beside it is two things — a textarea of a fixed height
     and the button — while the fields column is however many rows the chosen
     subject needs. Four rows instead of three and the button stops at the
     bottom of nothing, with the gap under it that the extra inputs added.
     Letting the textarea take the space that is left keeps the button on the
     last row's line whatever the subject asks for; with fewer rows there is
     nothing to take and the design's own height stands. */
  .elv-form .form-part:not(.--first):not(.--xl) > .form-item:has(textarea) {
    display: flex;
    -webkit-box-flex: 1;
        -ms-flex: 1;
            flex: 1;
  }

  .elv-form .form-part:not(.--first):not(.--xl) > .form-item:has(textarea) textarea {
    height: 100%;
  }
}

/* The chosen subject's extra inputs (inc/contact-form.php > elv_form_types).
   One block per subject, spanning the row and laying its own fields out in the
   same two columns — so a set of three reads
   [ a ][ b ] / [ c ], never split between the form's own columns. */
.form-extras {
  display: grid;
  gap: 1rem;
}

@media (orientation: landscape), (min-width: 769px) and (orientation: portrait) {
  .form-extras {
    grid-column: 1 / -1;
    grid-template-columns: repeat(2, 1fr);
    gap: 1rem 1.5rem;
  }

  /* An odd number of them leaves the last one alone on its row — it takes the
     whole width rather than sitting beside a gap. The pair before it stays
     side by side. One field on its own (the CV) is the same case. */
  .form-extras .form-item:last-child:nth-child(odd) {
    grid-column: 1 / -1;
  }
}

/* A subject with neither a Projects list nor a Category offers no project at
   all (inc/contact-form.php > elv_form_subject_project_ids), so there is
   nothing to pick — קריירה, פרסום ומדיה. theme.js hides the row and disables
   the select; [hidden] alone would do it, this only makes sure no later rule
   can put it back. The same goes for the extra inputs of every subject other
   than the chosen one. */
.elv-form .form-item.--project[hidden],
.elv-form .form-extras[hidden] {
  display: none;
}

.elv-form__error {
  display: block;
  margin-top: 0.375rem;
  font-size: 0.875rem;
  line-height: 1.3;
  color: #b00020;
}

/* A consent row is a flex line (box + text); the error needs a line of its own
   under both, not a third column beside them — hence flex-wrap.

   The text must then be told it may shrink: with the default flex-basis:auto
   its width is the whole unwrapped sentence, which does not fit beside the
   box, so the row wraps and the text drops UNDER the checkbox. flex:1 1 0 lets
   it take the space that is left and wrap its own lines, the way it did before
   the error line existed. */
.elv-form .checkbox-item {
  -ms-flex-wrap: wrap;
      flex-wrap: wrap;
}

.elv-form .checkbox-item > *:not(label):not(.elv-form__error) {
  -webkit-box-flex: 1;
      -ms-flex: 1 1 0%;
          flex: 1 1 0%;
  min-width: 0;
}

.elv-form .checkbox-item .elv-form__error {
  -ms-flex-preferred-size: 100%;
      flex-basis: 100%;
  margin-inline-start: 1.75rem;
}

/* The consent box itself is invisible — flag the drawn square and its text. */
.elv-form .checkbox-item.--invalid label span {
  border-color: #b00020;
  -webkit-box-shadow: 0 0 0 1px #b00020;
          box-shadow: 0 0 0 1px #b00020;
}

.elv-form .checkbox-item.--invalid p {
  color: #b00020;
}

/* The CV picker is a filled button with no border of its own to redden. */
.elv-form .file-input.--invalid label {
  -webkit-box-shadow: 0 0 0 2px #b00020;
          box-shadow: 0 0 0 2px #b00020;
}

.elv-form.--sending {
  opacity: 0.6;
  pointer-events: none;
}

/* ---------------------------------------------------------------------------
   Instagram tiles: what kind of post this is
   (content/sections/instagram-feeds.php).

   Instagram marks a video or Reel with a play badge and a post held at the top
   of the grid with a pin, both in the tile's top corner. The feed reads both
   off the post (inc/instagram.php); these draw them. Top RIGHT, physically, in
   both directions — that is where Instagram itself puts them, and it is where
   people look for them.
   --------------------------------------------------------------------------- */
.instagram-feeds__item:not(.--intro) {
  position: relative;
}

.instagram-feeds__badges {
  position: absolute;
  top: 0.625rem;
  right: 0.625rem;
  display: -webkit-box;
  display: -ms-flexbox;
  display: flex;
  gap: 0.375rem;
  /* The whole tile is the link — the badges must not eat the click. */
  pointer-events: none;
}

.instagram-feeds__badge {
  display: block;
  width: 1.5rem;
  height: 1.5rem;
  background-repeat: no-repeat;
  background-position: center;
  background-size: contain;
  /* The tiles are photographs: a white icon on a pale one needs an edge. */
  -webkit-filter: drop-shadow(0 1px 2px rgba(0, 0, 0, 0.45));
          filter: drop-shadow(0 1px 2px rgba(0, 0, 0, 0.45));
}

.instagram-feeds__badge.--video {
  background-image: url("assets/img/icons/ig-video.svg");
}

.instagram-feeds__badge.--pinned {
  background-image: url("assets/img/icons/ig-pinned.svg");
}

@media (max-width: 768px) and (orientation: portrait) {
  .instagram-feeds__badges {
    top: 0.5rem;
    right: 0.5rem;
    gap: 0.25rem;
  }

  .instagram-feeds__badge {
    width: 1.25rem;
    height: 1.25rem;
  }
}

/* ---------------------------------------------------------------------------
   Projects listing (content/sections/projects-page.php).

   The design draws the filter bar without states — no "this one is chosen", and
   no sub-categories at all, because the static page has none. Both are needed
   once the buttons come from the taxonomy, so they live here.
   --------------------------------------------------------------------------- */

/* Chosen category: the same filled look the buttons already take on hover, so
   nothing new is invented. */
.projects-filter .primary-btn.is-active {
  background: #00141C;
  color: #fff;
}

/* A category with children. The group is the hover area for its panel; the
   button inside it keeps behaving like any other button. */
.projects-filter__group {
  position: relative;
}

.projects-filter__sub {
  position: absolute;
  top: 100%;
  inset-inline-start: 0;
  z-index: 30;
  min-width: 100%;
  display: flex;
  flex-direction: column;
  padding: 0.5rem 0;
  margin-top: 0.25rem;
  background: #00141C;
  border-radius: 0.625rem;
  opacity: 0;
  visibility: hidden;
  -webkit-transition: opacity 0.5s ease, visibility 0.5s ease;
          transition: opacity 0.5s ease, visibility 0.5s ease;
}

.projects-filter__group:hover .projects-filter__sub,
.projects-filter__group:focus-within .projects-filter__sub {
  opacity: 1;
  visibility: visible;
}

.projects-filter__sub-item {
  display: block;
  padding: 0.375rem 1.25rem;
  color: #fff;
  font-size: 1.125rem;
  white-space: nowrap;
  -webkit-transition: opacity 0.5s ease;
          transition: opacity 0.5s ease;
}

.projects-filter__sub-item:hover,
.projects-filter__sub-item.is-active {
  opacity: 0.65;
}

/* On mobile the whole list is already a dropdown panel, so a second one that
   flies out of it would be unreachable — the children sit in the flow instead. */
@media (max-width: 768px) and (orientation: portrait) {
  .projects-filter__sub {
    position: static;
    opacity: 1;
    visibility: visible;
    margin-top: 0.375rem;
    padding: 0.375rem 0;
    background: transparent;
  }

  .projects-filter__sub-item {
    color: inherit;
    padding: 0.25rem 0.5rem;
    font-size: 1rem;
  }
}

/* Header General Settings icon next to the desktop language switcher. */
.header-settings-link {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 3rem;
  height: 3rem;
  min-width: 3rem;
  text-decoration: none;
}

.header-settings-link svg {
  width: 100%;
  height: 100%;
}

@media (max-width: 768px) and (orientation: portrait) {
  .header-settings-link {
    display: none !important;
  }
}

@media (orientation: landscape), (min-width: 769px) and (orientation: portrait) {
  .header-inner .contact-btn {
    opacity: 1 !important;
    visibility: visible !important;
  }
}
/* The phone's header is its own height, and scroll-padding reads the one name
   at both sizes — so the name has to mean the header that is actually there. */
@media (max-width: 768px) and (orientation: portrait) {
  :root {
    --header-height: var(--header-height-mob);
  }
}

/* THE BAR STICKS, on the listing and on a project's own page both — it is the
   way back to the other projects, and it is no use only at the top of a long
   page. One rule covers the two because it is one component either way
   (parts/projects-filter.php); a project's page only adds .project-page__nav
   to it.

   It parks under the FIXED header (assets/css/main.css: .header is position
   fixed, and the theme already carries its height as a variable), and sits
   below it in the stacking order so the open mobile menu still covers it.

   The design gave the bar a 65%-white background, which was written for a bar
   that nothing scrolled behind. Now that things do, the blur is what keeps the
   buttons readable over whatever is passing underneath. */
.projects-filter {
  position: -webkit-sticky;
  position: sticky;
  top: var(--header-height);
  z-index: 40;
  -webkit-backdrop-filter: blur(0.5rem);
          backdrop-filter: blur(0.5rem);
}

/* AND THIS IS WHAT LETS IT STICK ON THE LISTING.
   assets/css/main.css gives EVERY `section` overflow:hidden, and the listing's
   bar sits inside `section.projects-page` — a sticky element inside a clipped
   box sticks to THAT box's scrollport, which never scrolls, so the bar simply
   stayed where it was printed and looked like the rule had not been written.
   (A project's own page never had the problem: there the bar is a direct child
   of <main>.)

   Both axes, deliberately. overflow-y: visible against a hidden x computes back
   to auto — still a scroll container, still no sticky. This section has nothing
   to clip anyway: the grid is cards in a grid, and the one thing that does
   overflow, the card's image, clips itself (.project-item__media). */
.projects-page {
  overflow: visible;
}

/* The search box there is a real GET form, and it carries whatever was already
   in the projects page's URL as hidden fields. The design styles .projects-search
   input as a drawn box — display:block would beat the browser's own rule and
   turn each of those into a visible empty one. */
.projects-search input[type="hidden"] {
  display: none;
}

/* .projects-filter lays the bar out as a flex row — buttons first, search box
   taking what is left — so the buttons can no longer be held at 13.75rem each
   and spread across the full width. They take their content width, which is
   what they do on the listing. */
@media (orientation: landscape), (min-width: 769px) and (orientation: portrait) {
  .projects-filter.project-page__nav .projects-filter__btns-list .primary-btn {
    min-width: 0;
  }
}

/* On mobile the dropdown panel hangs off .projects-filter__btns now, not off
   the bar itself. Both carry the same 1.25rem inline padding, so the listing's
   own offset is the one that reaches the viewport edge — right: 0, measured
   from inside the bar, leaves the 100vw panel 1.25rem short. */
@media (max-width: 768px) and (orientation: portrait) {
  .projects-filter.project-page__nav .projects-filter__btns-list {
    right: -1.25rem;
  }
}

/* THE CARD'S TITLE LINE holds two things now — the project at one end, its
   status at the other. space-between is what puts the status on the LEFT in
   Hebrew and on the right in English, without either side being named: it is
   simply the end of the line, whichever way the line runs.

   baseline, not center: the project name is set a size larger than the rest of
   the line (assets/css/main.css: .project-item__title strong), and centring
   would leave the status floating against it. */
.project-item__title {
  display: -webkit-box;
  display: -ms-flexbox;
  display: flex;
  -webkit-box-align: baseline;
      -ms-flex-align: baseline;
          align-items: baseline;
  -webkit-box-pack: justify;
      -ms-flex-pack: justify;
          justify-content: space-between;
  gap: 0.75rem;
}

/* The name in bold and the city in the plain weight are one item, not two — the
   markup wraps them together (content/sections/projects-page.php) so the row's
   gap cannot open up between "אורנבך 11" and "ראשון לציון". */
.project-item__title-text {
  min-width: 0;
}

/* A note beside the name rather than a second title: smaller, plain weight, and
   never folded onto a line of its own. The auto margin is what holds it at the
   end even when it is the only thing on the line — space-between has nothing to
   space out then, and a lone status would sit where the name should be. */
.project-item__status {
  -webkit-box-flex: 0;
      -ms-flex: none;
          flex: none;
  margin-inline-start: auto;
  font-weight: 400;
  white-space: nowrap;
  opacity: 0.7;
}

/* theme.js hides a card by setting .hidden on it. The reset's [hidden] rule is
   only as specific as .project-item's own display:flex and comes earlier in the
   file, so it loses — this is what actually takes a filtered card out. */
.project-item[hidden] {
  display: none !important;
}

/* Nothing matched the filter or the search. */
.projects-empty {
  padding: 2rem 1.25rem 4rem;
  text-align: center;
  font-size: 1.5rem;
}

.projects-empty[hidden] {
  display: none;
}

/* Keyboard skip link — off-screen until it takes focus. */
.skip-link {
  position: absolute;
  inset-inline-start: -9999px;
  top: 0;
  z-index: 100;
  padding: 0.75rem 1.25rem;
  background: #fff;
  color: #000;
}

.skip-link:focus {
  inset-inline-start: 0;
}

/* A live Google map (inc/map.php) stands in for the design's picture of one,
   so it holds the picture's proportions — 1880x475 on desktop, 390x282 on the
   phone — and the section around it needs no change either way. */
.elv-map {
  width: 100%;
  aspect-ratio: 1880 / 475;
}

@media (max-width: 768px) and (orientation: portrait) {
  .elv-map {
    aspect-ratio: 390 / 282;
  }
}

/* The contact strip is a taller box than the project one — the same shape
   _inner.scss pins a video and an embed to (1880x715 / 430x715). */
.contact-page__map .elv-map {
  aspect-ratio: 1880/715;
}

@media (max-width: 768px) and (orientation: portrait) {
  .contact-page__map .elv-map {
    aspect-ratio: 430/715;
  }
}

/* A wider table than the compiled 77.5rem (main.css) — desktop only, so the
   phone keeps the section's own padding rather than a cap it never reaches. */
@media (orientation: landscape), (min-width: 769px) and (orientation: portrait) {
  .contact-page__contacts {
    max-width: 86.5rem;
    margin-inline: auto;
  }
}

/* Google draws its own links and controls inside; keep the site's underline
   and inherited colour out of them. */
.elv-map a {
  text-decoration: none;
}

/* ---------------------------------------------------------------------------
   The bottom bar (elv_bottom_footer()): the copyright on one side, the social
   icons in the middle, the studio credits on the other. It came after the
   design was compiled, so it is styled here — following .footer-middle, whose
   dark strip it closes the page with: the same colours and inline padding,
   stacked and centred on the phone.

   The parts are in reading order, so on this RTL site the copyright sits at
   the right and the credits at the left, as they are named.
   --------------------------------------------------------------------------- */
.bottom-footer {
  background: #00141C;
  color: #fff;
  font-size: 1rem;
}

.bottom-footer .parts-wrapper {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1.25rem;
  padding-block: 0.75rem;
}

/* The two texts are never the same length, so sharing what is left over is
   what actually holds the icons in the MIDDLE of the bar rather than in the
   middle of the gap between them. Both sides are printed even when empty, for
   the same reason. */
.bottom-footer .right-part,
.bottom-footer .left-part {
  flex: 1 1 0;
  min-width: 0;
}

.bottom-footer .left-part {
  text-align: end;
}

.bottom-footer .middle-part {
  display: flex;
  align-items: center;
  gap: 1.25rem;
  flex-shrink: 0;
}

.bottom-footer .social-link {
  display: block;
  transition: opacity 0.5s ease;
}

.bottom-footer .social-link svg,
.bottom-footer .social-link img {
  display: block;
  width: 1.375rem;
  height: 1.375rem;
  object-fit: contain;
}

@media (any-hover: hover) {
  .bottom-footer .social-link:hover {
    opacity: 0.65;
  }
}

@media (orientation: landscape), (min-width: 769px) and (orientation: portrait) {
  .bottom-footer .container {
    padding-inline: 11.875rem;
  }
}

@media (max-width: 768px) and (orientation: portrait) {
  .bottom-footer {
    font-size: 0.875rem;
  }

  .bottom-footer .container {
    padding-inline: 1.25rem;
  }

  .bottom-footer .parts-wrapper {
    flex-direction: column;
    align-items: center;
    text-align: center;
    gap: 0.75rem;
    padding-block: 1.25rem;
  }

  /* Stacked: the sides are lines of their own, so nothing is left to share. */
  .bottom-footer .right-part,
  .bottom-footer .left-part {
    flex: 0 0 auto;
    text-align: center;
  }

  /* The icons read best first on the phone, above the two lines of small text. */
  .bottom-footer .middle-part {
    order: -1;
    gap: 1.5rem;
  }

  .bottom-footer .social-link svg,
  .bottom-footer .social-link img {
    width: 1.5rem;
    height: 1.5rem;
  }

  /* An empty side is a spacer on the desktop bar, but stacked it would be an
     empty line with a gap under it. */
  .bottom-footer .right-part:empty,
  .bottom-footer .left-part:empty {
    display: none;
  }
}

/* =========================================================
   Short form over media — the consent pair
   ========================================================= */

/* The renewal form carries the same two boxes the SAY HELLO form does —
   marketing and privacy — and both live in ONE grid cell, beside the submit
   button (content/sections/renewal-cta.php). A cell each would push the button
   down a row, so the pair is stacked inside the cell instead. */
.renewal-cta__form-grid .form-item:has(.checkbox-item) {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
}

/* This form sits on a darkened photo and writes in white, so the #b00020 the
   rest of the site rejects fields in is all but unreadable on it. Everything
   the form says goes light instead — the same red, lifted until it reads on the
   backdrop — and the borders it reddens with it. */
.renewal-cta .elv-form__error,
.renewal-cta .elv-form__message.--error,
.renewal-cta .elv-form .checkbox-item.--invalid p,
.renewal-cta .elv-form .checkbox-item.--invalid a {
  color: #ff9a9a;
}

.renewal-cta .elv-form__message.--success {
  color: #fff;
}

/* The rejected input itself — theme.js flags the field, not its row. */
.renewal-cta .elv-form .--invalid {
  border-color: #ff9a9a !important;
}

/* The consent box is invisible; the drawn square is what turns red. */
.renewal-cta .elv-form .checkbox-item.--invalid label span {
  border-color: #ff9a9a;
  -webkit-box-shadow: 0 0 0 1px #ff9a9a;
          box-shadow: 0 0 0 1px #ff9a9a;
}

/* =========================================================
   Project intro (content/sections/project-intro.php)

   Came after the design was compiled, so it is styled here
   rather than in assets/scss — same rules the rest of the
   theme is built on: the mq-mob breakpoint
   (max-width:768px and portrait), rem on a vw root, and the
   colours the body already carries.

   FOUR BLOCKS IN ONE FLAT GRID, printed in the phone's
   reading order — logo column, lead, visual, text. The phone
   simply stacks them; the desktop names the cells, so the
   visual moves from BETWEEN the two blocks of copy to beside
   both of them without a second copy of any of it.
   ========================================================= */
.project-intro {
  position: relative;
  overflow: hidden;
}

.project-intro__inner {
  position: relative;
  display: grid;
}

.project-intro__side {
  display: -webkit-box;
  display: -ms-flexbox;
  display: flex;
  -webkit-box-orient: vertical;
  -webkit-box-direction: normal;
      -ms-flex-direction: column;
          flex-direction: column;
  -webkit-box-align: center;
      -ms-flex-align: center;
          align-items: center;
}

.project-intro__logo img {
  display: block;
  width: 100%;
  height: auto;
}

/* The logo swap — the plain logo on load, the dark one settling over it three
   seconds later. Only .--swap carries a dark logo, so a lone logo is never
   given an animation to sit through.

   The dark one is taken OUT of the flow and laid over the plain one, which
   keeps the column's height the plain picture's — otherwise the two would
   stack and the title below would jump down. The plain one fades out as the
   dark one arrives rather than simply being covered, because a logo with
   transparency would otherwise show both at once.

   It SETTLES rather than blinks: a slow ease-out over 1.2s, the dark one
   easing down from a hair oversized while the plain one shrinks away under it.
   Both halves share the same curve and timing, so the two never cross at a
   visible seam. */
.project-intro__logo.--swap {
  position: relative;
}

.project-intro__logo.--swap img + img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  -o-object-fit: contain;
     object-fit: contain;
  opacity: 0;
  -webkit-animation: elv-logo-in 1.2s cubic-bezier(0.22, 0.61, 0.36, 1) 3s forwards;
          animation: elv-logo-in 1.2s cubic-bezier(0.22, 0.61, 0.36, 1) 3s forwards;
}

.project-intro__logo.--swap img:first-child {
  -webkit-animation: elv-logo-out 1.2s cubic-bezier(0.22, 0.61, 0.36, 1) 3s forwards;
          animation: elv-logo-out 1.2s cubic-bezier(0.22, 0.61, 0.36, 1) 3s forwards;
}

@-webkit-keyframes elv-logo-in {
  from {
    opacity: 0;
    -webkit-transform: scale(1.04);
            transform: scale(1.04);
  }
  to {
    opacity: 1;
    -webkit-transform: scale(1);
            transform: scale(1);
  }
}

@keyframes elv-logo-in {
  from {
    opacity: 0;
    -webkit-transform: scale(1.04);
            transform: scale(1.04);
  }
  to {
    opacity: 1;
    -webkit-transform: scale(1);
            transform: scale(1);
  }
}

@-webkit-keyframes elv-logo-out {
  from {
    opacity: 1;
    -webkit-transform: scale(1);
            transform: scale(1);
  }
  to {
    opacity: 0;
    -webkit-transform: scale(0.98);
            transform: scale(0.98);
  }
}

@keyframes elv-logo-out {
  from {
    opacity: 1;
    -webkit-transform: scale(1);
            transform: scale(1);
  }
  to {
    opacity: 0;
    -webkit-transform: scale(0.98);
            transform: scale(0.98);
  }
}

/* The title arrives OUTLINED and fills in with the logo — same 1.2s curve on
   the same 3s delay, so the column settles as one thing rather than two.

   Drawn with the stroke rather than a second copy of the words: the title
   carries its own <br>s from the editor, which an attr()/pseudo-element copy
   could not reproduce.

   It starts LIGHT and outlined and ends 700 and solid, so the letters put on
   weight as they fill. Big Caslon ships one face (500, main.css @font-face), so
   the light end simply draws that face and the 700 end is the browser's own
   bolding of it — the change lands once, late, rather than creeping: the weight
   is held at 300 through the first 60%, which is also where the stroke hands
   over to the fill, so the one moment covers both.

   The stroke holds until the fill is most of the way in and only then leaves —
   dropping both together would wash the letters out at the midpoint, and
   dropping it at the end alone would snap a hairline of weight off. */
.project-intro__title {
  /* The state it STARTS in — light, unfilled, outlined in the colour it fills
     with, so the stroke it opens as and the solid it lands on are one ink.
     `forwards` holds the end state (700 / #000c2d) once it has run. Scoped to
     this title: .section-title carries no colour, and the rest of the site's
     titles keep the body's. */
  font-weight: 300;
  color: #000c2d;
  -webkit-text-stroke: 1px currentColor;
  -webkit-text-fill-color: transparent;
  -webkit-animation: elv-title-fill 1.2s cubic-bezier(0.22, 0.61, 0.36, 1) 3s forwards;
          animation: elv-title-fill 1.2s cubic-bezier(0.22, 0.61, 0.36, 1) 3s forwards;
}

@-webkit-keyframes elv-title-fill {
  from {
    font-weight: 300;
    -webkit-text-fill-color: transparent;
    -webkit-text-stroke-color: currentColor;
  }
  60% {
    font-weight: 300;
    -webkit-text-stroke-color: currentColor;
  }
  to {
    font-weight: 700;
    -webkit-text-fill-color: currentColor;
    -webkit-text-stroke-color: transparent;
  }
}

@keyframes elv-title-fill {
  from {
    font-weight: 300;
    -webkit-text-fill-color: transparent;
    -webkit-text-stroke-color: currentColor;
  }
  60% {
    font-weight: 300;
    -webkit-text-stroke-color: currentColor;
  }
  to {
    font-weight: 700;
    -webkit-text-fill-color: currentColor;
    -webkit-text-stroke-color: transparent;
  }
}

/* Asked for no motion: the swap still HAPPENS — it is the design, not an
   effect — it just happens at once instead of fading. */
@media (prefers-reduced-motion: reduce) {
  .project-intro__logo.--swap img + img,
  .project-intro__logo.--swap img:first-child,
  .project-intro__title {
    -webkit-animation-duration: 0.01ms;
            animation-duration: 0.01ms;
  }
}

.project-intro__lead {
  font-weight: 700;
}

.project-intro__media img,
.project-intro__media video {
  display: block;
  width: 100%;
  height: auto;
  margin-inline: auto;
}

/* --------------------------- Desktop --------------------------- */
@media (orientation: landscape), (min-width: 769px) and (orientation: portrait) {

  /* RTL reads the first named column at the RIGHT, which is where the design
     has the logo — so the areas need no direction of their own.

     The visual takes the widest share of the row: it is the thing the section
     is about, and the two columns of copy read fine narrower. */
  .project-intro__inner {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.55fr) minmax(0, 1fr);
    grid-template-areas:
      "side media lead"
      "side media text";
    -webkit-box-align: center;
        -ms-flex-align: center;
            align-items: center;
    gap: 1.5rem 4rem;
    padding: 6.25rem 8.125rem;
  }

  .project-intro__side {
    grid-area: side;
    gap: 6.25rem;
  }

  .project-intro__media {
    grid-area: media;
  }

  /* The two blocks of copy are separate cells so the visual beside them can
     span both — but they must still read as ONE block, so they are pulled to
     the join between their rows instead of each centring in its own. */
  .project-intro__lead {
    grid-area: lead;
    -ms-flex-item-align: end;
        align-self: end;
  }

  .project-intro__text {
    grid-area: text;
    -ms-flex-item-align: start;
        align-self: start;
  }

  /* Only one of the two filled in: it takes both rows, so it centres against
     the visual rather than hugging an empty half. */
  .project-intro__inner:not(:has(.project-intro__text)) .project-intro__lead,
  .project-intro__inner:not(:has(.project-intro__lead)) .project-intro__text {
    grid-row: 1 / -1;
    -ms-flex-item-align: center;
        align-self: center;
  }

  .project-intro__logo {
    width: 21.25rem;
  }

  .project-intro__title {
    font-size: 3.5rem;
  }

  .project-intro__lead,
  .project-intro__text {
    font-size: 1.25rem;
    text-align: justify;
  }

  /* No cap — it fills its column. rem is on a vw root here (assets/scss
     _global.scss), so it scales with the viewport instead of stranding a fixed
     width on a wide screen. */
  .project-intro__media {
    margin-inline: auto;
  }
}

/* ---------------------------- Phone ---------------------------- */
@media (max-width: 768px) and (orientation: portrait) {

  /* Source order IS the design's order here — logo, lead, visual, text. */
  .project-intro__inner {
    gap: 1.875rem;
    padding: 2.5rem 1.75rem 3rem;
  }

  .project-intro__side {
    gap: 1.75rem;
  }

  .project-intro__logo {
    width: 9.375rem;
  }

  .project-intro__title {
    font-size: 1.5rem;
  }

  .project-intro__lead {
    font-weight: 700;
    text-align: center;
  }

  .project-intro__text {
    text-align: justify;
  }
}

/* =========================================================
   Project area (content/sections/project-area.php)

   The media covers the whole band on arrival and draws back
   to its half when the section scrolls in, uncovering the
   copy that was behind it. ONE trigger: the section carries
   a bare data-aos, AOS adds .aos-animate (main.js, once),
   and everything below hangs off that — the pull-back first,
   the copy a beat later on transition-delay rather than on
   a trigger of its own.

   Same flat markup at both breakpoints — heading, media,
   text. The phone reads it in that order as it stands; the
   desktop lifts the media out of the flow and pins it to the
   side, so the two blocks of copy close up beside it.
   ========================================================= */
/* The band is INSET, not edge to edge — it stands off the sides of the screen
   by the same 1.25rem gutter the rest of the theme uses (.project-page__inner,
   assets/css/main.css). A margin rather than padding: the coloured band and the
   picture pinned inside it both have to stop at the gutter, and the picture is
   positioned against this box. */
.project-area {
  position: relative;
  overflow: hidden;
  background: #2F606F;
  color: #fff;
  margin-inline: 1.25rem;
}

.project-area__media img,
.project-area__media video,
.project-area__media .elv-embed-wrap {
  display: block;
  width: 100%;
  height: 100%;
  -o-object-fit: cover;
     object-fit: cover;
}

/* Decoration behind the copy — it must not eat clicks. */
.project-area .elv-embed {
  pointer-events: none;
}

.project-area__subtitle {
  font-family: 'Big Caslon', serif;
  text-align: center;
}

/* The copy waits for the media to get out of its way — hence the delay rather
   than a second scroll trigger. The `from` state is scoped to [data-aos] so it
   is only ever applied to a section AOS is actually driving.

   It RISES, it does not fade — the same rule the rest of the theme's reveals
   follow (see "The reveal rises, it does not fade" at the foot of this file):
   the copy is solid from the first frame and only travels the last 1.25rem. */
.project-area__head,
.project-area__text {
  -webkit-transition: -webkit-transform 0.9s ease 0.75s;
          transition: transform 0.9s ease 0.75s;
}

.project-area__text {
  -webkit-transition-delay: 0.9s;
          transition-delay: 0.9s;
}

.project-area[data-aos]:not(.aos-animate) .project-area__head,
.project-area[data-aos]:not(.aos-animate) .project-area__text {
  -webkit-transform: translateY(1.25rem);
          transform: translateY(1.25rem);
}

/* --------------------------- Desktop --------------------------- */
@media (orientation: landscape), (min-width: 769px) and (orientation: portrait) {

  /* The copy column, held at the inline END — the LEFT in Hebrew, the RIGHT in
     English, which is the side the design puts it on in each. It is
     margin-inline-START that is auto: the free space is pushed to the other
     side, leaving the column against the end edge without the stylesheet ever
     naming a direction. */
  .project-area__inner {
    width: 50%;
    margin-inline-start: auto;
    padding: 7.5rem 3.75rem;
  }

  /* The column is half the band; the copy inside it is a measure, centred —
     so the exact padding above never decides the line length. */
  .project-area__head,
  .project-area__text {
    position: relative;
    /* Above the media, which is positioned and comes after the heading in the
       source — without this it would paint over the title. */
    z-index: 1;
    max-width: 38rem;
    margin-inline: auto;
  }

  .project-area__subtitle {
    font-size: 1.625rem;
    margin-bottom: 1.5rem;
  }

  /* The subtitle now sits above it, so the title carries the gap down to the
     text — the big one that used to hang off the subtitle. */
  .project-area__title {
    margin-bottom: 3.75rem;
  }

  .project-area__text {
    font-size: 1.125rem;
    text-align: justify;
  }

  /* Out of the flow and pinned to the far side, so the heading and the text
     close up into one column beside it.

     Pinned by its inline-START — the OPPOSITE side to the copy, which sits at
     the inline end. Pinning both to the same side is what made the picture sit
     on top of the text.

     It is held by that edge and shrinks by WIDTH, which is what makes the far
     edge travel: in Hebrew the picture is held at the right and its left edge
     sweeps across to uncover the copy. Nothing here names a direction — the
     same rule sweeps the other way round on the English page. */
  .project-area__media {
    position: absolute;
    z-index: 0;
    inset-block: 0;
    inset-inline-start: 0;
    width: 50%;
    -webkit-transition: width 1.4s cubic-bezier(0.65, 0, 0.35, 1);
            transition: width 1.4s cubic-bezier(0.65, 0, 0.35, 1);
  }

  /* Before the section scrolls in: the picture covers the whole band. */
  .project-area[data-aos]:not(.aos-animate) .project-area__media {
    width: 100%;
  }
}

/* ---------------------------- Phone ---------------------------- */
@media (max-width: 768px) and (orientation: portrait) {

  /* Source order IS the design's order here — heading, picture, text — so the
     media stays in the flow and only the fade is kept. */
  .project-area__inner {
    padding: 3rem 1.5rem;
  }

  .project-area__subtitle {
    font-size: 1.125rem;
    margin-bottom: 1rem;
  }

  .project-area__title {
    margin-bottom: 1rem;
  }

  .project-area__media {
    margin-block: 2rem;
  }

  .project-area__media img,
  .project-area__media video {
    height: auto;
  }

  .project-area__text {
    text-align: justify;
  }
}

/* =========================================================
   Project specs (content/sections/project-specs.php)

   The heading on one side, the icon strip on the other,
   and the open tab's panel across the bottom.

   ONE FLAT LIST in the phone's reading order — heading,
   icons, panels. The desktop names the three cells
   (grid-template-areas), so the heading and the strip come
   up onto one row and the panel spans beneath them, with
   nothing repeated and nothing hidden per breakpoint. RTL
   reads the first named column at the RIGHT, which is where
   the design puts the heading, so the areas need no
   direction of their own.

   THE LIT ICON IS ONE FILE, not two: the black icon is
   turned white with a filter over the brand square, so an
   editor uploads one SVG and the two states can never drift
   apart.
   ========================================================= */
.project-specs__inner {
  display: grid;
  padding-inline: 1.25rem;
}

/* No Big Caslon here — the line is Hebrew, and that face has no Hebrew to set
   it in. It keeps the body font (main.css: AlmoniDLAAA). */

/* The strip. It wraps rather than scrolls: an icon that has moved off the edge
   of a phone is an icon nobody presses. */
.project-specs__tabs {
  display: -webkit-box;
  display: -ms-flexbox;
  display: flex;
  -ms-flex-wrap: wrap;
      flex-wrap: wrap;
  -webkit-box-align: center;
      -ms-flex-align: center;
          align-items: center;
  -webkit-box-pack: center;
      -ms-flex-pack: center;
          justify-content: center;
}

.project-specs__tab {
  display: -webkit-box;
  display: -ms-flexbox;
  display: flex;
  -webkit-box-align: center;
      -ms-flex-align: center;
          align-items: center;
  -webkit-box-pack: center;
      -ms-flex-pack: center;
          justify-content: center;
  padding: 0;
  border: 0;
  border-radius: 0.5rem;
  background: transparent;
  color: inherit;
  cursor: pointer;
  -webkit-transition: background 0.35s ease;
  transition: background 0.35s ease;
}

.project-specs__tab img {
  display: block;
  width: 100%;
  height: 100%;
  -o-object-fit: contain;
     object-fit: contain;
  -webkit-transition: -webkit-filter 0.35s ease;
  transition: filter 0.35s ease;
  transition: filter 0.35s ease, -webkit-filter 0.35s ease;
}

.project-specs__tab.is-active {
  background: #2F606F;
}

/* brightness(0) flattens the mark to black whatever colour it was drawn in,
   then invert(1) makes it white — so any icon reads on the brand square. */
.project-specs__tab.is-active img {
  -webkit-filter: brightness(0) invert(1);
          filter: brightness(0) invert(1);
}

/* Set against the same edge the list is, not centred over it — the heading and
   the bullets read as one block that way. */
.project-specs__panel-title {
  text-align: start;
}

/* The panel is a measure, centred under the strip — the section is as wide as
   the page and a list this long would otherwise run the whole way across. */
.project-specs__panel {
  margin-inline: auto;
}

/* Said out loud rather than left to the browser default: a later `display` on
   any of these wrappers would otherwise bring every closed panel back. */
.project-specs__panel[hidden] {
  display: none;
}

/* A tabpanel is focusable so the keyboard lands in the copy after the arrows —
   but it is not a control, so it gets no ring until it is reached by keyboard. */
.project-specs__panel:focus:not(:focus-visible) {
  outline: none;
}

.project-specs__panel .editor-area ul {
  list-style: disc;
  padding-inline-start: 1.25rem;
}

/* --------------------------- Desktop --------------------------- */
@media (orientation: landscape), (min-width: 769px) and (orientation: portrait) {

  /* The heading holds one column, the strip the other, and the panel drops into
     the STRIP's column underneath it — not across the whole section. That is
     what puts the copy under the icons instead of stranded in the middle of the
     page, and it is why the panel and the strip share an edge below.

     align-items: start, so the heading stays at the top of its column beside
     the icons rather than centring against a panel that can be any height. */
  .project-specs__inner {
    grid-template-columns: minmax(0, 1fr) minmax(0, 2fr);
    grid-template-areas:
      "head tabs"
      ".    panels";
    -webkit-box-align: start;
        -ms-flex-align: start;
            align-items: start;
    gap: 2.5rem 2rem;
    padding-block: 5rem;
    padding-inline: 13.25rem;
  }

  /* The whole head block reads against the edge the language starts from —
     start, not right: it is the right in Hebrew and the left in English, so the
     English page mirrors instead of setting the title against the wrong edge.
     The Hebrew subtitle leads and the Latin title sits under it. */
  .project-specs__head {
    grid-area: head;
    text-align: start;
  }

  .project-specs__title {
    font-size: 3rem;
    text-align: start;
  }

  .project-specs__subtitle {
    font-size: 1.375rem;
    margin-bottom: 0.5rem;
  }

  /* Both are held at the column's inline START — the RIGHT in Hebrew — so the
     strip and the copy under it line up on one edge, the way the design draws
     them. Centring either one is what pulled them apart. */
  .project-specs__tabs {
    grid-area: tabs;
    gap: 6rem;
    -webkit-box-pack: start;
        -ms-flex-pack: start;
            justify-content: flex-start;
  }

  .project-specs__tab {
    width: 6rem;
    height: 6rem;
    padding: 0.625rem;
  }

  .project-specs__panels {
    grid-area: panels;
  }

  .project-specs__panel {
    max-width: 24rem;
    margin-inline-start: 0;
    margin-inline-end: auto;
  }

  .project-specs__panel-title {
    font-size: 1.25rem;
    margin-bottom: 1.25rem;
  }

  .project-specs__panel .editor-area {
    font-size: 1rem;
  }
}

/* ---------------------------- Phone ---------------------------- */
@media (max-width: 768px) and (orientation: portrait) {

  .project-specs__inner {
    gap: 2rem;
    padding-block: 3rem;
  }

  /* NOT the desktop's reading here. The phone centres the head and puts the
     Latin title ON TOP with the Hebrew line under it — the design's own order,
     and the reverse of the desktop's.

     The markup is printed subtitle-first for the desktop, so the phone turns
     the head into a flex column and lifts the title with `order` rather than
     printing either line twice. gap carries the space between them, so neither
     one needs a margin that would have to be unpicked at the other size. */
  .project-specs__head {
    display: -webkit-box;
    display: -ms-flexbox;
    display: flex;
    -webkit-box-orient: vertical;
    -webkit-box-direction: normal;
        -ms-flex-direction: column;
            flex-direction: column;
    gap: 0.5rem;
    text-align: center;
  }

  /* Two classes, not one: project-intro.php prints a flat `.section-title` in
     the body, which lands AFTER this file and would otherwise set the size
     from there. 2rem is that block's phone number, said here as well so the
     title reads the same on a page that has no project-intro on it. */
  .project-specs__title.section-title {
    -webkit-box-ordinal-group: 0;
        -ms-flex-order: -1;
            order: -1;
    font-size: 2rem;
  }

  .project-specs__subtitle {
    font-size: 1.125rem;
    margin-bottom: 0;
  }

  .project-specs__tabs {
    gap: 1rem;
  }

  .project-specs__tab {
    width: 3.75rem;
    height: 3.75rem;
    padding: 0.75rem;
  }

  .project-specs__panel-title {
    font-size: 1.125rem;
    margin-bottom: 1rem;
  }
}

/* =========================================================
   Project showcase (content/sections/project-showcase.php)

   It wears .project-page's own classes, so the grid, the
   proportions and the slider all come from the compiled
   stylesheet. Only the deltas live here.
   ========================================================= */

/* THE RULE THAT CLOSES THE SECTION. The slider ends on its dots, which leaves
   the next section with nothing to start against — so the showcase draws the
   design's own 1px line under itself.

   A pseudo-element rather than a border on the section: the line has to stop at
   the 1.25rem gutter, and a border would run the full width. Nothing here moves
   the layout — it only draws. */
/* ROOM AT THE TOP. The design's .project-page__inner opens on 1.125rem, which
   was written for the details section sitting straight under the project's own
   nav bar. This one follows another section, so it needs the same air above it
   that it already has below — one number, matched to the padding-bottom the
   compiled stylesheet gives it. */
.project-page.--showcase .project-page__inner {
  position: relative;
  padding-top: 5rem;
}

@media (max-width: 768px) and (orientation: portrait) {
  .project-page.--showcase .project-page__inner {
    padding-top: 3rem;
  }
}

.project-page.--showcase .project-page__inner::after {
  content: '';
  position: absolute;
  bottom: 0;
  inset-inline: 1.25rem;
  border-bottom: 1px solid #00141C;
}

/* The line under a slide — the picture's Media Library Caption. */
.project-page.--showcase .project-page__caption {
  display: block;
  margin-top: 1.25rem;
  text-align: center;
  font-size: 1.125rem;
}

/* EVERY SLIDE IS THE SAME HEIGHT, cropped to it, so the slider never resizes
   between a tall picture and a wide one — and a video is sized like a picture,
   which the design's stylesheet only ever did for an img.

   The height is a custom property so it is one number to change, and it is in
   rem — the root is on a vw here (assets/scss/_global.scss), so it scales with
   the viewport instead of stranding a fixed strip on a wide screen. */
.project-page.--showcase {
  --showcase-slide-h: 30rem;
}

.project-page.--showcase .swiper-slide {
  position: relative;
}

.project-page.--showcase .swiper-slide img,
.project-page.--showcase .swiper-slide video {
  display: block;
  width: 100%;
  height: var(--showcase-slide-h);
  -o-object-fit: cover;
     object-fit: cover;
}

/* A YouTube/Vimeo slide is an iframe inside .elv-embed-wrap, which already
   covers whatever box it is given (style.css, top of file) — so it only needs
   the height, not the object-fit. */
.project-page.--showcase .swiper-slide .elv-embed-wrap {
  height: var(--showcase-slide-h);
}

/* Cropping hides part of the picture, so every slide gets the way back to the
   whole of it: the corner button opens the file at full size in Fancybox.

   Pinned by inset-inline-end, so it sits in the corner nearest the reader in
   Hebrew and in English without naming a side. */
.project-page.--showcase .project-page__zoom {
  position: absolute;
  top: 1.25rem;
  inset-inline-end: 1.25rem;
  z-index: 2;
  display: -webkit-box;
  display: -ms-flexbox;
  display: flex;
  -webkit-box-align: center;
      -ms-flex-align: center;
          align-items: center;
  -webkit-box-pack: center;
      -ms-flex-pack: center;
          justify-content: center;
  width: 3rem;
  height: 3rem;
  border-radius: 50%;
  color: #00141C;
  background: rgba(240, 236, 228, 0.85);
  -webkit-backdrop-filter: blur(2px);
          backdrop-filter: blur(2px);
  cursor: pointer;
  -webkit-transition: background 0.3s ease, -webkit-transform 0.3s ease;
  transition: background 0.3s ease, transform 0.3s ease;
}

.project-page.--showcase .project-page__zoom svg {
  width: 1.5rem;
  height: 1.5rem;
}

.project-page.--showcase .project-page__zoom:hover,
.project-page.--showcase .project-page__zoom:focus-visible {
  background: #F0ECE4;
  -webkit-transform: scale(1.08);
      -ms-transform: scale(1.08);
          transform: scale(1.08);
}

/* ------------------- Beside: the copy in a column next to the slider -------------

   THE GRID IS THE DESIGN'S OWN — the column of copy beside a 67.9375rem slab,
   straight out of the compiled stylesheet. Nothing here touches it: the copy
   already sets and wraps the way the design has it, and the only thing that was
   ever wrong was the size of the picture.

   So this narrows the SLIDER inside its column and centres it, which turns the
   wide crop into the portrait card the design draws. The slide is then simply
   as wide as the slider, so there is no half of a second picture hanging off
   the side and no second zoom button on it.

   Two numbers, and they are the card:
     38rem  wide (the slider's own box)
     42rem  tall (--showcase-slide-h)

   Read them as a share of the screen: the root is 0.83333vw (main.css), so the
   viewport is 120rem wide at every width — 38rem is 31.7% of it, which is what
   the design measures. */
@media (orientation: landscape), (min-width: 769px) and (orientation: portrait) {

  .project-page.--showcase:not(.--stacked) {
    --showcase-slide-h: 42rem;
  }

  .project-page.--showcase:not(.--stacked) .project-page__media {
    max-width: 38rem;
    margin-inline: auto;
  }
}

/* ------------------- Stacked: copy above, slider full width -------------------

   The SAME markup as the layout beside it — the Layout field only adds
   .--stacked. The design's grid is two columns; here it collapses to one, the
   copy centres in it, and the slider runs nearly the whole width of the screen
   underneath.

   NEARLY, not all of it: it is held at 95vw and centred, so the page's edge
   stays visible down both sides instead of the picture running off them. One
   number — --stacked-slider-w — and it is a share of the screen, so it holds at
   every width. */
.project-page.--showcase.--stacked {
  --stacked-slider-w: 95vw;
}

/* The phone's gutter is 4.65vw a side (1.25rem on a 3.72vw root), so the column
   is already narrower than 95vw — asking for 95vw there would push the slider
   past its own column and hand the page a sideways scroll. It simply fills the
   column instead. */
@media (max-width: 768px) and (orientation: portrait) {
  .project-page.--showcase.--stacked {
    --stacked-slider-w: 100%;
  }
}

.project-page.--showcase.--stacked .project-page__inner {
  -ms-grid-columns: 1fr;
  grid-template-columns: 1fr;
}

/* Wider than the column it sits in, so it needs the width said out loud AND
   the max-width the design puts on nothing here to get out of its way. */
.project-page.--showcase.--stacked .project-page__media {
  width: var(--stacked-slider-w);
  max-width: var(--stacked-slider-w);
  margin-inline: auto;
}

/* Both are centred measures — the design's widths were written for a column
   beside the slider, and here the copy has the whole page to sit in. The
   HEADING is centred text; the paragraphs under it are not, they keep the
   justified setting the rest of the theme reads in. */
.project-page.--showcase.--stacked .project-page__header {
  margin-inline: auto;
  text-align: center;
}

.project-page.--showcase.--stacked .project-page__content .editor-area {
  margin-inline: auto;
  text-align: justify;
}

@media (orientation: landscape), (min-width: 769px) and (orientation: portrait) {

  .project-page.--showcase.--stacked {
    --showcase-slide-h: 42rem;
  }

  .project-page.--showcase.--stacked .project-page__inner {
    padding-bottom: 3.75rem;
  }

  .project-page.--showcase.--stacked .project-page__header {
    max-width: 48rem;
  }

  .project-page.--showcase.--stacked .project-page__content .editor-area {
    max-width: 36rem;
    margin-top: 2.5rem;
  }
}

/* The details section has no subtitle on the phone, so the design hides h3
   there. This one is a title AND a line under it at both sizes. */
@media (max-width: 768px) and (orientation: portrait) {

  /* rem is on a much bigger vw root on the phone (1rem ≈ 16px at 430px), so
     the desktop number would be a half-screen strip — its own height here. */
  .project-page.--showcase {
    --showcase-slide-h: 16rem;
  }

  /* THE SLIDER GOES LAST on the phone — heading, copy, then the pictures.

     The design's stylesheet pulls .project-page__media up with order:-2, which
     is the Project DETAILS section's phone order; the showcase borrows those
     classes but not that reading. Handing the media a positive order drops it
     back behind .project-page__content, which has none — and the heading keeps
     the -4 that already puts it first. */
  .project-page.--showcase .project-page__media {
    -webkit-box-ordinal-group: 2;
        -ms-flex-order: 1;
            order: 1;
  }

  .project-page.--showcase .project-page__zoom {
    top: 0.75rem;
    inset-inline-end: 0.75rem;
    width: 2.5rem;
    height: 2.5rem;
  }

  .project-page.--showcase .project-page__zoom svg {
    width: 1.25rem;
    height: 1.25rem;
  }

  .project-page.--showcase .project-page__header h3 {
    display: block;
    margin-bottom: 0;
    font-size: 1.125rem;
  }

  .project-page.--showcase .project-page__caption {
    margin-top: 1rem;
    font-size: 1rem;
  }
}

/* A pull-back this wide is motion, not decoration — asked for none, the copy
   is simply there and the picture is already at its half. */
@media (prefers-reduced-motion: reduce) {

  .project-area__head,
  .project-area__text,
  .project-area__media {
    -webkit-transition: none;
            transition: none;
  }

  .project-area[data-aos]:not(.aos-animate) .project-area__head,
  .project-area[data-aos]:not(.aos-animate) .project-area__text {
    -webkit-transform: none;
            transform: none;
  }
}

/* Only the desktop pins the picture, so only the desktop has a width to put
   back. On a phone it is a picture in the flow and 50% would simply shrink it. */
@media (prefers-reduced-motion: reduce) and (orientation: landscape),
       (prefers-reduced-motion: reduce) and (min-width: 769px) and (orientation: portrait) {

  .project-area[data-aos]:not(.aos-animate) .project-area__media {
    width: 50%;
  }
}


/* =========================================================
   Thank-you popup (parts/thanks-popup.php)

   The old site's answer to "פרויקטים עתידיים": the page
   dimmed and a white card over it, rather than the line
   under the button. A subject asks for it on its own row
   (General Settings > Contact form > Subjects) and the
   server says so in the response — theme.js only adds
   .active here.

   Hidden by visibility, not display: the card fades in, and
   visibility:hidden already takes the X and the button out
   of the tab order — display:none would leave nothing to
   transition.

   It is printed at the FOOT of the page, outside the form's
   section, because the section is animated in with a
   transform and a transformed ancestor turns position:fixed
   into position:absolute — the overlay would scroll off
   with the form instead of covering the page.
   ========================================================= */
.container-thanks-popup {
  position: fixed;
  inset: 0;
  z-index: 99;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 1.5rem;
  background: rgba(0, 0, 0, 0.4);
  opacity: 0;
  visibility: hidden;
  -webkit-transition: opacity 0.3s ease, visibility 0.3s ease;
          transition: opacity 0.3s ease, visibility 0.3s ease;
}

.container-thanks-popup.active {
  opacity: 1;
  visibility: visible;
}

/* Centred by the overlay's own flex box, so a card that grows past the screen
   scrolls instead of hanging off the top — the old site's fixed 23% could not. */
.thanks-popup {
  position: relative;
  width: 40rem;
  max-width: 100%;
  max-height: 100%;
  overflow-y: auto;
  padding: 1.25rem 1.25rem 3.5rem;
  background: #fff;
  color: #00141C;
  text-align: center;
}

/* The card takes the focus when it has no button to give it to (script only,
   see parts/thanks-popup.php) — a ring around the whole card is not something
   a mouse user asked for, a keyboard one still gets it. */
.thanks-popup:focus:not(:focus-visible) {
  outline: none;
}

/* Top LEFT in Hebrew and in English both — the design's X does not follow the
   reading direction, so it is a physical side, not an inset-inline one. */
.thanks-popup .close {
  position: absolute;
  top: 1rem;
  left: 1rem;
  display: flex;
  padding: 0;
  border: 0;
  background: none;
  color: inherit;
  cursor: pointer;
}

.thanks-popup .close svg {
  width: 1.75rem;
  height: 1.75rem;
}

.thanks-popup .text {
  padding: 3.5rem 2rem 0;
}

.thanks-popup .title {
  font-size: 3rem;
  font-weight: 700;
  line-height: 1.1;
}

.thanks-popup .subtext {
  margin-top: 1.25rem;
  font-size: 1.375rem;
  line-height: 1.25;
}

/* The old site underlined the last line ("עם תחילת שיווק הפרויקט!") — the
   client writes it as bold, so bold IS that line. */
.thanks-popup .subtext strong {
  text-decoration: underline;
}

.thanks-popup__action {
  margin-top: 2.5rem;
}

/* The page behind it must not scroll while it is open: the popup is the whole
   answer, and a phone would otherwise wander off it under a finger. */
.elv-thanks-open,
.elv-thanks-open body {
  overflow: hidden;
}

@media (max-width: 768px) and (orientation: portrait) {

  .thanks-popup {
    padding-bottom: 2.5rem;
  }

  .thanks-popup .close {
    top: 0.75rem;
    left: 0.75rem;
  }

  .thanks-popup .text {
    padding: 2.5rem 0 0;
  }

  .thanks-popup .title {
    font-size: 1.75rem;
  }

  .thanks-popup .subtext {
    margin-top: 1rem;
    font-size: 1.0625rem;
  }

  .thanks-popup__action {
    margin-top: 2rem;
  }
}

/* Asked for no motion, it is simply there. */
@media (prefers-reduced-motion: reduce) {

  .container-thanks-popup {
    -webkit-transition: none;
            transition: none;
  }
}

/* =========================================================
   Projects 2 (content/sections/projects-2.php)
   ========================================================= */

/* The details block is one <p> of label/value lines, and a project with fewer
   rows than its neighbour was pulling its button up level with the others'
   text. A floor under the paragraph puts every button on one line instead.

   No breakpoint on it: main.css already hides the inner block on the phone
   (it opens behind the "more" button there), so this only ever reaches the
   desktop. */
.projects-2__item-content-inner p {
  min-height: 15rem;
}

/* THE PHONE OPENS ON THE HOVER STATE — the rendering and the coloured logo,
   not the line drawing.

   Both pictures are in the markup at both sizes (projects-2.php prints
   .--default and .--hover); main.css only ever crosses them over under
   `@media (any-hover: hover)`, so a finger never reaches the second one and
   the card sat on the drawing forever. Here the pair is simply swapped —
   .--hover is the one that is up, and .--default is the one that is not.

   Two classes deep on both, to match the specificity main.css sets .--default
   with; one class would lose to it however late this file loads. */
@media (max-width: 768px) and (orientation: portrait) {

  .projects-2__item-logo .--default,
  .projects-2__item-image .--default {
    opacity: 0;
  }

  .projects-2__item-logo .--hover,
  .projects-2__item-image .--hover {
    opacity: 1;
  }
}

/* =========================================================
   Header (header.php)
   ========================================================= */

/* THE CALL BUTTON COMES TO THE PHONE — burger at the right, logo in the
   middle, the call at the left.

   It was never a missing button: the header's third cell holds the call AND
   the language switcher together (header.php), and main.css hides that whole
   cell on the phone. The switcher is the one that is meant to go — it has a
   second copy inside the open menu — but the call went with it. So the cell
   comes back, and the switcher is hidden on its own instead.

   The row also becomes the desktop's three-column grid. space-between cannot
   centre the logo: the burger and the call are different widths, so the logo
   settled off-centre by the difference between them. 1fr auto 1fr centres it
   on the SCREEN, whatever the two ends measure.

   RTL needs nothing of its own — the first column is the right in Hebrew,
   which is the burger, and the third is the left, which is the call. The
   `justify-self: end` main.css already puts on that cell holds it there. */
@media (max-width: 768px) and (orientation: portrait) {

  .header-inner {
    display: -ms-grid;
    display: grid;
    -ms-grid-columns: 1fr auto 1fr;
    grid-template-columns: 1fr auto 1fr;
  }

  .header-inner div:has(.lang-switcher) {
    display: -webkit-box;
    display: -ms-flexbox;
    display: flex;
  }

  .header-inner .lang-switcher {
    display: none;
  }
}

/* =========================================================
   CTA section (content/sections/cta-section.php)
   ========================================================= */

/* The design gives each item `flex: 0 1 31.25rem` so two of them sit side by
   side on the desktop. On the phone the ROW turns into a COLUMN (main.css),
   and a flex-basis on a column item is read down the page, not across — so
   that 31.25rem stops being a width and becomes a height, and each item
   reserves half a screen of empty space under its button.

   unset hands it back `0 1 auto`: the item is as tall as what is in it. */
@media (max-width: 768px) and (orientation: portrait) {

  .cta-section__content-item {
    -webkit-box-flex: unset;
        -ms-flex: unset;
            flex: unset;
  }
}

/* =========================================================
   Renewal stats (content/sections/renewal-stats.php)
   ========================================================= */

/* The figure is read off the SCREEN on the phone, not off the root: 10vw,
   where main.css has a fixed 3.4375rem. Same thing at one width and a bigger
   number at every other — a small phone stops shrinking it into the label
   under it, a large one stops leaving it stranded in the middle of its box.

   justify-content is the half main.css leaves out. The number is a flex row
   (it has to be — the digits ride in on a transform behind `overflow:hidden`),
   and text-align cannot centre a flex ITEM: the span sat at the start of the
   box whatever the text inside it said. */
@media (max-width: 768px) and (orientation: portrait) {

  .renewal-stats__item .number {
    font-weight: 400;
    font-size: 10vw;
    text-align: center;
    -webkit-box-pack: center;
        -ms-flex-pack: center;
            justify-content: center;
  }
}

/* =========================================================
   THE REVEAL RISES, IT DOES NOT FADE

   Every scroll reveal in the sections is AOS's `fade-up` —
   a 24px rise AND an opacity 0 → 1
   (assets/libs/aos/scss/_animations.scss). The rise is the
   design; the fade is not wanted. So only the opacity is
   taken away: the element is solid from the first frame and
   still travels the same distance, on the same curve, with
   the same per-item delays (data-aos-delay) behind it.

   Written at the two-attribute specificity AOS uses itself,
   and this file loads after the compiled bundle
   (inc/assets.php), so it wins on order. AOS's own
   transition-property (opacity, transform) is left alone —
   with the opacity never changing there is nothing for it to
   animate.

   A bare `data-aos="fade"` would now have nothing left to
   do, so a reveal is always given a DIRECTION — fade-up,
   fade-left — which is what the sections already use.

   The reveals written without a fade in the first place need
   nothing here: the Press rows sliding out from the side and
   the Renewal figures rolling up behind overflow:hidden are
   transforms, and the Project area's copy is handled at its
   own block above.
   ========================================================= */
[data-aos^='fade'][data-aos^='fade'],
[data-aos^='fade'][data-aos^='fade'].aos-animate {
  opacity: 1;
}

/* =========================================================
   THE SCRIM — words on a picture, and the picture goes 35%
   black under them.

   One rule for the whole site: wherever a section lays copy
   or a project logo OVER its media, the media carries a flat
   black veil at 35% and the words read against it. The
   design shipped this per block and at three different
   strengths (0.3, 0.4, and nothing at all in places) — here
   there is one value, in one place, and every block takes it.

   AND IT COVERS A VIMEO / YOUTUBE EMBED TOO, which is the
   half that was missing. The veil is a ::before of the media
   box, and an .mp4 or an <img> is not positioned, so it
   simply paints over them. An embed is: inc/media.php wraps
   the iframe in .elv-embed-wrap, which is position:relative
   and comes after the pseudo-element in the box — so it was
   painting on top of the veil and a Vimeo background sat
   there undimmed while the same section with an .mp4 in it
   was dimmed. The veil is lifted to z-index 1 to clear it,
   and `isolation: isolate` on the media box keeps that 1
   INSIDE the box — it can never rise over the copy that is
   its sibling.

   Adding a new section that puts words over a picture? Add
   its media box to the two lists below rather than writing
   another veil of its own.
   ========================================================= */
:root {
  /* The one value. */
  --elv-scrim: rgba(0, 0, 0, 0.35);
}

/* The boxes the design left unpositioned — the veil needs an edge to sit
   against. The rest are already absolute or relative. */
.page-hero__media,
.page-preview__media,
.cta-section__media {
  position: relative;
}

/* A stacking context per media box, so the veil's z-index is spent inside it
   and nowhere else. Safe on an absolutely positioned box — unlike `position`,
   it takes nothing away. */
.page-hero__media,
.page-preview__media,
.cta-section__media,
.about-vision__media,
.about-features__media,
.footer-form__media,
.renewal-cta__media,
.renewal-stats__media,
.projects__item-media {
  isolation: isolate;
}

/* THE VEIL. .page-hero is listed twice on purpose: main.css draws its own at
   0.4 through `:not(.--home)`, which is a heavier selector than the plain one,
   so the plain one alone would lose to it. Listing both means the home hero
   gets a veil it never had and the inner pages get this value instead of
   theirs.

   Nothing here says `opacity` — the two blocks that fade their veil in on
   hover / on the active slide (.projects__item-media, and .project-item below)
   keep doing exactly that, in this colour. */
.page-hero__media::before,
.page-hero:not(.--home) .page-hero__media::before,
.page-preview:has(.page-preview__content) .page-preview__media::before,
.cta-section__media:has(> *)::before,
.about-vision__media::before,
.about-features__media::before,
.footer-form__media::before,
.renewal-cta__media::before,
.renewal-stats__media::before,
.projects__item-media::before {
  position: absolute;
  content: "";
  inset: 0;
  z-index: 1;
  background: var(--elv-scrim);
  /* Decoration — it must not eat a click meant for the card under it. */
  pointer-events: none;
}

/* A project card on the listing carries its logo INSIDE the media box (at
   z-index 20), and its veil is already at 5 — above an embed, below the logo.
   So only the colour is said here; the layering there is right as it is. */
.project-item__media::before {
  background: var(--elv-scrim);
}

/* The Process card has no veil of its own: its content box covers the whole
   picture and IS the veil (main.css). It is a positioned sibling that comes
   after the media, so it already darkens an embed — only the colour changes. */
.process-page__item-content {
  background: var(--elv-scrim);
}

/* =========================================================
   .contact-btn — the number that slides out on hover
   ========================================================= */

/* main.css builds the slide-out (position, max-width transition) on
   .contact-btn itself, but scopes the label's own layout to .fixed-btns.
   The header phone button has the same markup, so the two bits are said
   here for every .contact-btn instead — the asterisk needs the gap and the
   baseline nudge wherever it appears. */
.contact-btn span {
  display: inline-flex;
  align-items: center;
  gap: 0.25rem;
}

.contact-btn i {
  position: relative;
  top: 0.6rem;
}

/* …and main.css hides the label on mobile portrait at a lower specificity
   than the rule above, so that hiding is repeated here to survive it. */
@media (max-width: 768px) and (orientation: portrait) {
  .contact-btn span {
    display: none;
  }
}

/* A floating button sits at the screen edge, so main.css anchors its number
   on the left and lets it grow right, into the page. The header button sits
   in the last grid column next to the language switcher, and the free space
   is on the far side of it from the switcher — the switcher must not be
   covered. In Hebrew that free side is the right, which is the direction
   main.css already grows: nothing to say. In English the button is to the
   LEFT of the switcher, so there the number is anchored on its right edge
   and grows left instead. Physical properties, not logical ones: the label
   carries direction:ltr of its own (the number always reads LTR), so an
   inset-inline-* here would resolve against THAT and not the page. The
   English pages ship no dir attribute at all, hence :not([dir="rtl"]). */
html:not([dir="rtl"]) .header-inner .contact-btn span {
  left: auto;
  right: 4rem;
}

/* The menu chevron is the desktop hover cue: it slides into the padding main.css
   only reserves above mobile. On a phone a tap sets .isActive on the item, so it
   would slide in over the label with nothing to slide into. */
@media (max-width: 768px) and (orientation: portrait) {

  .main-menu__wrapper > ul > li > a::before {
    content: none;
  }
}

/* =========================================================
   reCAPTCHA v3 (inc/recaptcha.php)
   ========================================================= */

/* Google's floating badge, hidden. Their terms allow it ONLY when the credit
   line is shown in the form instead — elv_recaptcha_notice() prints it under
   every submit button, so do not remove one without the other.
   visibility, not display: the widget still has to render for the token to be
   minted, and display:none has been known to break it. */
.grecaptcha-badge {
  visibility: hidden;
}

.elv-recaptcha-note {
  margin-top: 0.75rem;
  font-size: 0.75rem;
  line-height: 1.5;
  opacity: 0.6;
}

.elv-recaptcha-note a {
  text-decoration: underline;
}

/* =========================================================
   Process cards — sound toggle, and the clip not being cropped
   ========================================================= */

/* The clip fills the card — an uploaded <video> by object-fit, an embedded
   player by the size/centring rules further down (an iframe ignores
   object-fit). Both crop, because a 16/9 clip cannot fill a 455/809 box any
   other way; the black behind them is only ever seen while a player boots.
   To show the WHOLE frame instead, letterboxed, this is `contain` and the
   .elv-embed block below drops its two min-* lines. */
.process-page__item-media {
  position: relative;
  background: #000;
}

.process-page__item-media video {
  -o-object-fit: cover;
     object-fit: cover;
}

/* Play and the sound toggle, side by side. LTR on the pair so the sound icon
   is to the RIGHT of play in Hebrew as well — a mirrored row would throw it to
   the far side of the card. */
.process-page__item-actions {
  direction: ltr;
  display: flex;
  align-items: center;
  gap: 0.5rem;
  flex-shrink: 0;
}

.process-page__item-content .head .mute-video {
  width: 2.5rem;
  height: 2.5rem;
  padding: 0.5rem;
  border-radius: 50%;
  color: #fff;
  background: rgba(0, 0, 0, 0.35);
  backdrop-filter: blur(2px);
  -webkit-backdrop-filter: blur(2px);
  display: flex;
  align-items: center;
  justify-content: center;
  transition: 0.3s ease background;
}

@media (any-hover: hover) {
  .process-page__item-content .head .mute-video:hover {
    background: rgba(0, 0, 0, 0.6);
  }
}

.mute-video__img {
  position: relative;
  display: block;
  width: 100%;
  height: 100%;
}

.mute-video__img svg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  transition: 0.3s ease opacity;
}

/* Sound on: the speaker with its waves. Muted: the crossed-out one. */
.mute-video__img .--off {
  opacity: 0;
}

.mute-video.is-muted .mute-video__img .--on {
  opacity: 0;
}

.mute-video.is-muted .mute-video__img .--off {
  opacity: 1;
}

/* The head text slides away while the clip runs (main.css), and the buttons
   stay — so the toggle is reachable exactly when there is something to mute. */

/* main.css gives .play-video a ::before with inset:0 — and since .play-video
   itself is not positioned, that box resolves against .process-page__item-content
   and quietly covers the WHOLE card, which is what makes anywhere on it start
   the clip. It would cover the sound toggle too, and a positioned pseudo-element
   paints over a static sibling, so the toggle is lifted out of its way. Without
   this the mute button plays the video instead of muting it. */
.process-page__item-content .head .mute-video {
  position: relative;
  z-index: 2;
}

/* ---------------------------------------------------------
   Process cards — the embed filling the card
   ---------------------------------------------------------
   inc/media.php wraps a YouTube / Vimeo clip in .elv-embed-wrap, and
   main.css gives that a 16/9 box. In a 455/809 card that leaves the player
   sized to the wrong shape entirely, which is what was pushing the title out
   of the top of the card. Here the wrapper simply IS the card, and the iframe
   covers it the way an object-fit:cover video would (an iframe ignores
   object-fit, so it is done with size + centring instead).

   Scoped to this section on purpose: everywhere else — the full-bleed hero,
   the contact map — the 16/9 box is right, and a global rule would break them.

   Percentages, not the vw/vh of the usual snippet: those measure the VIEWPORT,
   and a card is a third of it, so 100vw/177.78vh would blow the player up to
   several times the card and crop away nearly all of it. aspect-ratio with two
   minimums does the same job against the CARD. */

.process-page__item-media .elv-embed-wrap {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  aspect-ratio: auto;
  overflow: hidden;
  background-size: cover;
  background-position: center;
}

.process-page__item-media .elv-embed {
  position: absolute;
  top: 50%;
  left: 50%;
  -webkit-transform: translate(-50%, -50%);
      -ms-transform: translate(-50%, -50%);
          transform: translate(-50%, -50%);
  width: auto;
  height: auto;
  min-width: 100%;
  min-height: 100%;
  aspect-ratio: 16 / 9;
  border: 0;
}

/* The card's overlay — title, spec list, the buttons — must stay on top of the
   player. The media box is positioned now (it has to be, for the wrapper to
   anchor to it), so without an explicit order the iframe can paint over the
   controls — which is what made the pause icon disappear. */
.process-page__item-media {
  z-index: 0;
}

.process-page__item-content {
  z-index: 1;
}

/* The buttons are flex items now (.process-page__item-actions) and a button
   with a fixed 4rem box will still be squeezed by a tight row. */
.process-page__item-content .head .play-video,
.process-page__item-content .head .mute-video {
  flex-shrink: 0;
}

/* The sound toggle belongs to a clip that is RUNNING. At rest the card shows
   the design's play icon alone; the moment it plays — hovered, or pinned by a
   press — the icon becomes pause and the speaker joins it on its right.
   visibility as well as opacity, so a hidden button is not tabbable and cannot
   be clicked through the card's play hit-area. */
.process-page__item-content .head .mute-video {
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  -webkit-transition: 0.3s ease opacity, 0.3s ease visibility, 0.3s ease background;
  transition: 0.3s ease opacity, 0.3s ease visibility, 0.3s ease background;
}

.process-page__item.is-playing .head .mute-video {
  opacity: 1;
  visibility: visible;
  pointer-events: auto;
}

/* main.css slides the card's text away while the clip runs with
   `.is-playing .head > div` — written when .head held exactly one div (the
   title and the meta line) beside a bare <button>. The buttons live in a div of
   their own now, so that rule catches them too and the pause / sound icons
   vanish the moment they are needed. They are put back here.

   Not solved by making the wrapper a <span>: the controls staying put while the
   text leaves is the rule, and it should be written down, not implied by a tag
   name someone could reasonably change later. */
.process-page__item.is-playing .head > .process-page__item-actions {
  -webkit-transform: none;
      -ms-transform: none;
          transform: none;
  opacity: 1;
  visibility: visible;
}

/* =========================================================
   MENU PREVIEWS - the clip fades up through its still.

   A preview is hovered, not scrolled to, so the clip is
   never ready at the moment it is asked for: the still
   appears first and the player then cuts in on top of it,
   which reads as a glitch rather than as a picture coming
   to life.

   So the box holds the still (the poster painted on
   .page-preview__media by inc/header-footer.php, or the one
   .elv-embed-wrap already carries behind an embed) and the
   clip itself starts transparent. theme.js
   (initMenuEmbeds) puts .is-shown on it once it is really
   running - the `playing` event for an uploaded file, the
   frame's load or Vimeo's `ready` for an embed - and it
   crossfades in from there.

   Leaving the item takes the class off again, so the next
   hover starts from the still and not mid-shot.
   ========================================================= */
.page-preview__media {
  background-size: cover;
  background-position: center;
}

.page-preview__media video,
.page-preview__media .elv-embed {
  opacity: 0;
  -webkit-transition: opacity 0.7s ease;
  transition: opacity 0.7s ease;
}

.page-preview__media video.is-shown,
.page-preview__media .elv-embed.is-shown {
  opacity: 1;
}
