/* OMEGA motion.
   The whole file is inert under prefers-reduced-motion: the tokens collapse to
   0ms/0px in tokens.css, and the two behaviours that a duration cannot flatten
   are guarded explicitly at the bottom. */

/* -----------------------------------------------------------------------------
 * Scroll reveal
 *
 * omega-reveal-ready is set by JS, so the hidden state only ever exists on a
 * page that has something running to un-hide it.
 * -------------------------------------------------------------------------- */

.omega-reveal-ready [data-omega-reveal] {
  opacity: 0;
  transform: translateY(var(--omega-rise));
  transition: opacity 620ms var(--omega-ease), transform 620ms var(--omega-ease);
}

.omega-reveal-ready [data-omega-reveal].omega-revealed {
  opacity: 1;
  transform: none;
}

/* Children of a revealed group arrive in sequence rather than together. */
.omega-reveal-ready [data-omega-reveal] > * {
  transition: opacity 520ms var(--omega-ease), transform 520ms var(--omega-ease);
}

.omega-reveal-ready [data-omega-reveal-stagger] > * {
  opacity: 0;
  transform: translateY(calc(var(--omega-rise) * 0.7));
}

.omega-reveal-ready [data-omega-reveal-stagger].omega-revealed > * {
  opacity: 1;
  transform: none;
}

.omega-reveal-ready [data-omega-reveal-stagger].omega-revealed > *:nth-child(2) { transition-delay: 70ms; }
.omega-reveal-ready [data-omega-reveal-stagger].omega-revealed > *:nth-child(3) { transition-delay: 140ms; }
.omega-reveal-ready [data-omega-reveal-stagger].omega-revealed > *:nth-child(4) { transition-delay: 210ms; }
.omega-reveal-ready [data-omega-reveal-stagger].omega-revealed > *:nth-child(5) { transition-delay: 280ms; }
.omega-reveal-ready [data-omega-reveal-stagger].omega-revealed > *:nth-child(6) { transition-delay: 350ms; }
.omega-reveal-ready [data-omega-reveal-stagger].omega-revealed > *:nth-child(7) { transition-delay: 420ms; }

/* -----------------------------------------------------------------------------
 * Front-page header
 *
 * --omega-header-progress runs 0 (over the hero) to 1 (landed). The mark
 * travels from the centre of the hero into the brand slot, and the bar fades
 * its ground in underneath. Sticky from the start, so nothing jumps at the
 * moment it lands.
 * -------------------------------------------------------------------------- */

.omega-home-header-managed {
  --omega-header-progress: 0;
  /* The mark's width at the current progress: 540 over the hero, 150 in the
     header, which is exactly the brand width on every other route. */
  --omega-mark-width: calc(540px - 390px * var(--omega-header-progress));
}

/* Fixed, not sticky. Sticky would reserve a band at the top of the document
   and push the hero down; fixed lets the hero keep the full viewport and the
   bar float over it, which is what the overlay already did — it just could not
   follow the scroll. */
.omega-home-header-managed .omega-site-header--overlay {
  position: fixed;
  z-index: 30;
  inset: 0 0 auto;
  height: auto;
  min-height: 86px;
  padding: 24px var(--omega-gutter);
  /* Ground and rule arrive together with progress, so the bar becomes the
     ordinary header rather than switching to it at a threshold. */
  border-bottom: 1px solid rgba(220, 215, 202, calc(0.14 * var(--omega-header-progress)));
  background: rgba(20, 21, 15, var(--omega-header-progress));
}

/* A plain overflow:hidden does not clip fixed children, but the front page
   sets one and the intent there is only to stop horizontal bleed. Say that. */
.omega-workshop-front .omega-site-frame.omega-home-header-managed {
  overflow-x: clip;
  overflow-y: visible;
}

/* The mark. One element is both the hero wordmark and the header brand, so
   there is no cross-fade seam where two logos are briefly both present. */
.omega-home-header-managed .omega-home-hero__mark {
  position: fixed;
  z-index: 31;
  inset-block-start: calc(210px - 186px * var(--omega-header-progress));
  inset-inline: 0;
  display: flex;
  justify-content: center;
  /* Travelling to the start edge by shrinking the box the mark is centred in,
     rather than translating it. A percentage here resolves against the
     viewport, where a percentage in translateX would resolve against the
     mark's own width and drift as the mark shrinks. */
  padding-inline-end: calc(
    (100% - 2 * var(--omega-gutter) - var(--omega-mark-width)) * var(--omega-header-progress)
  );
  pointer-events: none;
}

.omega-home-header-managed .omega-home-hero__mark img {
  width: var(--omega-mark-width);
  opacity: calc(0.95 + 0.05 * var(--omega-header-progress));
}

/* The origin note and the mark occupy the same corner once the header lands —
   the mark travels to the gutter, which is exactly where "Cairo · est. 1994"
   sits — so the two were printed over each other on any scrolled front page.
   The note yields as the mark arrives, on the same progress the travel uses, so
   they hand over rather than cross-fade at a threshold.

   `visibility` follows at the end rather than opacity alone, so the note is not
   left as an invisible target for a screen reader or a pointer. */
.omega-home-header-managed .omega-site-header__origin {
  opacity: calc(1 - var(--omega-header-progress));
}

.omega-home-header-managed .omega-site-header--landed .omega-site-header__origin {
  visibility: hidden;
}

/* Landed, the mark is the brand: it takes the pointer back so it is clickable
   the way the brand is on every other route. */
.omega-home-header-managed .omega-site-header--landed + nav .omega-home-hero__mark,
.omega-home-header-managed .omega-home-hero__mark:has(a) {
  pointer-events: auto;
}

/* -----------------------------------------------------------------------------
 * Home tiles
 * -------------------------------------------------------------------------- */

.omega-home-tile img {
  transition: transform 720ms var(--omega-ease), opacity 130ms linear;
}

/* The caption is the image block's own figcaption now, not a class of ours. */
.omega-home-tile figcaption {
  transition: background-color var(--omega-dur) var(--omega-ease);
}

.omega-home-tile__name {
  display: inline-block;
  transition: transform var(--omega-dur) var(--omega-ease);
}

.omega-frame-swapping {
  opacity: 0;
}

@media (prefers-reduced-motion: no-preference) and (hover: hover) {
  .omega-home-tile:hover img,
  .omega-home-tile:focus-visible img {
    transform: scale(1.04);
  }

  .omega-home-tile:hover .omega-home-tile__name,
  .omega-home-tile:focus-visible .omega-home-tile__name {
    transform: translateX(4px);
  }

  [dir="rtl"] .omega-home-tile:hover .omega-home-tile__name {
    transform: translateX(-4px);
  }
}

.omega-home-tile:hover figcaption,
.omega-home-tile:focus-visible figcaption {
  background: rgba(20, 21, 15, 0.96);
}

/* The catalogue tile is text, not a photograph — its rule extends instead. */
.omega-home-tile--catalogue .omega-home-tile__link {
  transition: border-color var(--omega-dur) var(--omega-ease), color var(--omega-dur) var(--omega-ease);
}

.omega-home-tile--catalogue:hover .omega-home-tile__link {
  border-bottom-color: var(--omega-stone);
}

/* Category strip and the workshop link: the rule draws in from the start edge
   rather than appearing. */
.omega-home-categories a,
.omega-home-workshop__link,
.omega-workshop-cta__secondary,
.omega-cart-empty__secondary {
  position: relative;
}

.omega-home-categories a::after {
  position: absolute;
  inset: auto var(--omega-s-5) 18px;
  height: 1px;
  background: var(--omega-ember);
  content: "";
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform var(--omega-dur) var(--omega-ease);
}

[dir="rtl"] .omega-home-categories a::after {
  transform-origin: right center;
}

.omega-home-categories a:hover::after,
.omega-home-categories a:focus-visible::after {
  transform: scaleX(1);
}

/* -----------------------------------------------------------------------------
 * Timber tiles — the grain reveal
 *
 * The field lifts and saturates on hover. When the grain photographs exist they
 * become the field's background-image and this same rule reveals them.
 * -------------------------------------------------------------------------- */

.omega-workshop-timber::before {
  background-position: center;
  background-size: cover;
  transition: transform 820ms var(--omega-ease), filter 420ms var(--omega-ease);
}

.omega-workshop-timber h3 {
  transition: transform var(--omega-dur) var(--omega-ease);
}

@media (prefers-reduced-motion: no-preference) and (hover: hover) {
  .omega-workshop-timber:hover .omega-workshop-timber::before {
    transform: scale(1.06);
    filter: saturate(1.15) brightness(1.06);
  }

  .omega-workshop-timber:hover h3 {
    transform: translateY(-4px);
  }
}

/* -----------------------------------------------------------------------------
 * Rewards
 *
 * A stroke drawn once across the thing that just worked, the way a line is
 * drawn on a workshop drawing. Never a bounce, never a colour flash.
 * -------------------------------------------------------------------------- */

.omega-marked {
  position: relative;
  overflow: hidden;
}

.omega-marked::after {
  position: absolute;
  z-index: 2;
  inset: 0;
  background: linear-gradient(
    100deg,
    transparent 0%,
    rgba(174, 140, 81, 0.16) 42%,
    rgba(220, 215, 202, 0.34) 50%,
    rgba(174, 140, 81, 0.16) 58%,
    transparent 100%
  );
  content: "";
  pointer-events: none;
  transform: translateX(-100%);
  animation: omega-stroke 760ms var(--omega-ease) both;
}

@keyframes omega-stroke {
  to { transform: translateX(100%); }
}

/* The basket count is the one number that means "it worked". It steps up in
   weight and colour, then settles. */
.omega-site-header__basket-count {
  display: inline-block;
  transition: color var(--omega-dur) var(--omega-ease);
}

.omega-count-ticked {
  animation: omega-count-tick 700ms var(--omega-ease) both;
  color: var(--omega-bronze);
}

@keyframes omega-count-tick {
  0%   { transform: translateY(0) scale(1); }
  28%  { transform: translateY(-3px) scale(1.28); }
  60%  { transform: translateY(0) scale(1); }
  100% { transform: none; }
}

/* A variation chosen settles into place rather than snapping. */
.omega-variation-option {
  transition: background-color var(--omega-dur-fast) var(--omega-ease),
              color var(--omega-dur-fast) var(--omega-ease),
              border-color var(--omega-dur-fast) var(--omega-ease);
}

/* Add to cart: the fill sweeps from the start edge on hover, and the label
   holds still while it does. */
.omega-product-purchase .single_add_to_cart_button,
.omega-button {
  position: relative;
  overflow: hidden;
  transition: background-color var(--omega-dur) var(--omega-ease),
              color var(--omega-dur) var(--omega-ease),
              border-color var(--omega-dur) var(--omega-ease);
}

.omega-button:hover,
.omega-product-purchase .single_add_to_cart_button:not(.disabled):not(:disabled):hover {
  background: var(--omega-paper);
}

/* The commission submit, while it is being sent. */
.omega-button--sending {
  color: transparent !important;
}

.omega-button--sending::after {
  position: absolute;
  inset-block-start: 50%;
  inset-inline-start: 50%;
  width: 16px;
  height: 16px;
  margin: -8px 0 0 -8px;
  border: 1px solid rgba(23, 23, 20, 0.3);
  border-block-start-color: var(--omega-ink);
  border-radius: 50%;
  content: "";
  animation: omega-spin 700ms linear infinite;
}

@keyframes omega-spin {
  to { transform: rotate(360deg); }
}

/* -----------------------------------------------------------------------------
 * The explicit reduced-motion floor
 *
 * Durations already collapse via tokens. These are the effects that a 0ms
 * duration would not silence, so they are removed outright.
 * -------------------------------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
  .omega-reveal-ready [data-omega-reveal],
  .omega-reveal-ready [data-omega-reveal-stagger] > * {
    opacity: 1;
    transform: none;
  }

  .omega-marked::after,
  .omega-count-ticked,
  .omega-button--sending::after {
    animation: none;
  }

  .omega-marked::after {
    display: none;
  }

  .omega-button--sending {
    color: inherit !important;
    opacity: 0.6;
  }

  .omega-home-tile img,
  .omega-workshop-timber::before {
    transition: none;
  }
}
