/* ---------------------------------------------------------------------------
   TechPlast components.

   Loaded after fonts.css, tokens.css and motion.css. Nothing here names a colour
   or a duration -- those come from the token layer, which is what lets the theme
   and the whole motion system be retuned without touching this file.
   --------------------------------------------------------------------------- */

/* ============================ Base ====================================== */
*, *::before, *::after { box-sizing: border-box; }

html {
  font-size: 16px;
  scroll-behavior: smooth;
  /* The header is fixed, so an in-page anchor would otherwise land under it. */
  scroll-padding-top: calc(var(--header-h) + 1rem);
  -webkit-text-size-adjust: 100%;
}

body {
  margin: 0;
  color: var(--text);
  background: var(--surface);
  font-family: var(--font-body);
  font-size: var(--step-0);
  line-height: 1.65;
  font-synthesis-weight: none;
  text-rendering: optimizeLegibility;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

h1, h2, h3, h4 {
  font-family: var(--font-display);
  font-weight: 600;
  line-height: 1.06;
  letter-spacing: -.03em;
  text-wrap: balance;
}

h1 { font-size: var(--step-5); margin: 0 0 var(--space-4); }
h2 { font-size: var(--step-4); margin: 0 0 var(--space-4); }
h3 { font-size: var(--step-2); margin: 0 0 var(--space-3); }
p { text-wrap: pretty; }

a {
  color: var(--accent-text);
  text-decoration-thickness: 1px;
  text-underline-offset: 4px;
  transition: color var(--dur-1) var(--ease-soft);
}

a:hover { color: var(--accent-hover); }
img { max-width: 100%; }

::selection { color: var(--text-on-brand); background: var(--accent); }

:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
  border-radius: var(--radius-xs);
}

.skip-link {
  position: fixed;
  inset-inline-start: 1rem;
  top: -6rem;
  z-index: 9999;
  padding: .8rem 1.2rem;
  border-radius: var(--radius-pill);
  color: var(--text-on-brand);
  background: var(--brand);
  font-weight: 600;
  text-decoration: none;
  transition: top var(--dur-2) var(--ease-spring);
}

.skip-link:focus { top: 1rem; color: var(--text-on-brand); }

/* ============================ Layout ==================================== */
.container { width: min(1240px, calc(100% - 2.5rem)); margin-inline: auto; }
.narrow { max-width: 68ch; }
.section { padding-block: var(--space-9); }
.section-muted { background: var(--surface-sunken); }
.page-hero + .section { padding-top: clamp(2.5rem, 5vw, 4rem); }

/* A hairline that only exists to separate two same-coloured bands. */
.section + .section:not(.section-muted) { border-top: 1px solid var(--border-hair); }

/* ---- Type utilities ---- */
.eyebrow {
  display: inline-flex;
  align-items: center;
  gap: .6rem;
  color: var(--accent-text);
  font-family: var(--font-body);
  font-size: var(--step--2);
  font-weight: 600;
  letter-spacing: .18em;
  text-transform: uppercase;
}

/* The rule reads as a typographic mark rather than a border because it grows
   into place with the heading it belongs to. */
.eyebrow::before {
  content: "";
  width: 1.75rem;
  height: 1px;
  background: currentColor;
  transform-origin: 0 50%;
  transition: transform var(--dur-3) var(--ease-out-expo);
}

[data-reveal] .eyebrow::before,
.eyebrow.is-growing::before { transform: scaleX(0); }
[data-reveal].is-in .eyebrow::before { transform: scaleX(1); }
.eyebrow.on-dark { color: var(--accent-text); }

.section-heading {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: var(--space-6);
  margin-bottom: var(--space-7);
}

.section-heading h2 { margin: var(--space-3) 0 0; max-width: 20ch; }
.section-heading > a { align-self: flex-end; }

/* A link whose arrow travels on hover. The gap is animated rather than the
   arrow position so nothing is knocked out of the text baseline. */
.arrow-link {
  display: inline-flex;
  align-items: center;
  gap: .5rem;
  color: var(--text);
  font-weight: 600;
  text-decoration: none;
  white-space: nowrap;
}

.arrow-link span[aria-hidden] {
  display: grid;
  place-items: center;
  width: 2rem;
  height: 2rem;
  border: 1px solid var(--border-strong);
  border-radius: 50%;
  transition:
    transform var(--dur-2) var(--ease-out-expo),
    background-color var(--dur-2) var(--ease-soft),
    border-color var(--dur-2) var(--ease-soft),
    color var(--dur-2) var(--ease-soft);
}

.arrow-link:hover { color: var(--accent-text); }

.arrow-link:hover span[aria-hidden] {
  color: var(--text-on-brand);
  border-color: var(--accent);
  background: var(--accent);
  transform: translateX(.25rem);
}

[dir="rtl"] .arrow-link span[aria-hidden] { transform: scaleX(-1); }
[dir="rtl"] .arrow-link:hover span[aria-hidden] { transform: scaleX(-1) translateX(.25rem); }

/* ============================ Buttons =================================== */
.btn {
  --btn-bg: transparent;
  --btn-fg: var(--text);
  --btn-line: var(--border-strong);
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: .55rem;
  padding: .78rem 1.5rem;
  overflow: hidden;
  border: 1px solid var(--btn-line);
  border-radius: var(--radius-pill);
  color: var(--btn-fg);
  background: var(--btn-bg);
  font-family: var(--font-body);
  font-size: var(--step--1);
  font-weight: 600;
  letter-spacing: -.005em;
  line-height: 1.3;
  text-decoration: none;
  transition:
    transform var(--dur-2) var(--ease-spring),
    box-shadow var(--dur-2) var(--ease-soft),
    background-color var(--dur-2) var(--ease-soft),
    border-color var(--dur-2) var(--ease-soft),
    color var(--dur-2) var(--ease-soft);
}

.btn:hover, .btn:focus-visible { color: var(--btn-fg); transform: translateY(-2px); }
.btn:active { transform: translateY(0) scale(.985); }
.btn[aria-disabled="true"] {
  transform: none;
  box-shadow: none;
  cursor: wait;
}
.btn-lg { padding: .95rem 1.9rem; font-size: var(--step-0); }
.btn-sm { padding: .45rem 1rem; font-size: var(--step--2); }

/* A submitted form owns its controls until navigation completes. This prevents
   a fast double click from creating two quotes, uploads, or destructive admin
   requests, while leaving the focused button in place for keyboard users. */
form.is-submitting :is(button, input[type="submit"], input[type="image"]) {
  pointer-events: none;
}

.button-spinner {
  position: relative;
  z-index: 1;
  display: inline-block;
  flex: 0 0 auto;
  width: 1em;
  height: 1em;
  border: 2px solid currentColor;
  border-inline-end-color: transparent;
  border-radius: 50%;
  animation: button-spin 650ms linear infinite;
  vertical-align: -.12em;
}

@keyframes button-spin { to { transform: rotate(1turn); } }

/* The wash is a pseudo-element rather than a background-position animation so
   it can be skewed, and so the label stays put while the fill moves under it. */
.btn::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 0;
  background: linear-gradient(100deg, transparent 20%, rgba(255, 255, 255, .22) 50%, transparent 80%);
  transform: translateX(-120%) skewX(-18deg);
  transition: transform var(--dur-4) var(--ease-out-expo);
}

.btn:hover::after { transform: translateX(320%) skewX(-18deg); }
.btn > * { position: relative; z-index: 1; }

.btn-brand {
  --btn-bg: var(--accent);
  --btn-fg: #fff;
  --btn-line: var(--accent);
  box-shadow: var(--shadow-ember);
}

.btn-brand:hover, .btn-brand:focus-visible {
  --btn-bg: var(--accent-hover);
  --btn-line: var(--accent-hover);
  --btn-fg: #fff;
}

.btn-outline-light {
  --btn-fg: #fff;
  --btn-line: rgba(255, 255, 255, .38);
}

.btn-outline-light:hover, .btn-outline-light:focus-visible {
  --btn-fg: var(--navy-900);
  --btn-bg: #fff;
  --btn-line: #fff;
}

.btn-light {
  --btn-bg: #fff;
  --btn-fg: var(--navy-900);
  --btn-line: #fff;
}

.btn-light:hover, .btn-light:focus-visible { --btn-fg: var(--navy-900); box-shadow: var(--shadow-lg); }

.btn-outline-navy, .btn-outline-secondary {
  --btn-fg: var(--text);
  --btn-line: var(--border-strong);
}

.btn-outline-navy:hover, .btn-outline-navy:focus-visible,
.btn-outline-secondary:hover, .btn-outline-secondary:focus-visible {
  --btn-fg: var(--text-on-brand);
  --btn-bg: var(--brand);
  --btn-line: var(--brand);
}

.btn-primary {
  --btn-bg: var(--brand);
  --btn-fg: var(--text-on-brand);
  --btn-line: var(--brand);
}

.btn-primary:hover, .btn-primary:focus-visible { --btn-bg: var(--brand-hover); --btn-line: var(--brand-hover); }

.btn-danger {
  --btn-bg: var(--danger);
  --btn-fg: #fff;
  --btn-line: var(--danger);
}

.btn-link {
  --btn-line: transparent;
  --btn-fg: var(--accent-text);
  padding-inline: .5rem;
  text-decoration: underline;
}

.link-button {
  padding: 0;
  border: 0;
  background: none;
  color: var(--text-muted);
  font-family: inherit;
  font-size: var(--step--1);
  font-weight: 600;
  text-decoration: underline;
  text-underline-offset: 3px;
  cursor: pointer;
  transition: color var(--dur-1) var(--ease-soft);
}

.link-button:hover { color: var(--danger); }

.back-link {
  display: inline-flex;
  align-items: center;
  gap: .45rem;
  color: var(--text-muted);
  font-weight: 600;
  text-decoration: none;
  transition: gap var(--dur-2) var(--ease-out-expo), color var(--dur-1) var(--ease-soft);
}

.back-link:hover { gap: .75rem; color: var(--accent-text); }

/* ============================ Header ==================================== */
/* The bar belongs to the page now, not to a dark band laid over it. Every page
   opens on the ground colour -- cream by day, near-black by night -- so the
   header takes the raised surface and the ordinary ink, and reads correctly in
   both themes without a single hard-coded colour. */
.site-header {
  position: fixed;
  z-index: 100;
  inset-block-start: 0;
  inset-inline: 0;
  border-bottom: 1px solid var(--border-hair);
  background: var(--surface-raised);
  transition:
    transform var(--dur-3) var(--ease-out-expo),
    background-color var(--dur-3) var(--ease-soft),
    border-color var(--dur-3) var(--ease-soft),
    box-shadow var(--dur-3) var(--ease-soft);
}

.site-header.is-stuck {
  border-bottom-color: var(--border);
  box-shadow: var(--shadow-sm);
}

@supports (backdrop-filter: blur(1px)) {
  .site-header.is-stuck {
    background: var(--glass);
    backdrop-filter: blur(18px) saturate(1.4);
  }
}

.site-header.is-hidden { transform: translateY(-104%); }
body.public-site { padding-top: 0; }

.site-header .navbar { min-height: var(--header-h); padding: .85rem 0; transition: min-height var(--dur-3) var(--ease-soft); }
.site-header.is-stuck .navbar { min-height: 64px; }

.brand { display: inline-flex; align-items: center; padding: 0; }

/* No plate and no movement. The mark stands on the header's own surface, and
   a logo that flinches when the pointer passes it is a logo nobody trusts. */
.brand img {
  display: block;
  width: auto;
  height: 44px;
  max-width: 168px;
  object-fit: contain;
}

.site-header .nav-link {
  position: relative;
  color: var(--text-muted);
  font-size: var(--step--1);
  font-weight: 500;
  padding: .55rem .8rem !important;
  transition: color var(--dur-1) var(--ease-soft);
}

/* The page you are on, named in the brand colour with a rule under it. */
.site-header .nav-link.is-current { color: var(--accent-text); }
.site-header .nav-link.is-current::after { transform: scaleX(1); }

.site-header .nav-link::after {
  content: "";
  position: absolute;
  inset-inline: .8rem;
  bottom: .3rem;
  height: 1.5px;
  background: var(--ember-400);
  transform: scaleX(0);
  transform-origin: 0 50%;
  transition: transform var(--dur-2) var(--ease-out-expo);
}

[dir="rtl"] .site-header .nav-link::after { transform-origin: 100% 50%; }
.site-header .nav-link:hover, .site-header .nav-link:focus { color: var(--text); }
.site-header .nav-link:hover::after, .site-header .nav-link:focus::after { transform: scaleX(1); }

.site-header .nav-cta {
  margin-inline-start: .35rem;
  padding: .55rem 1.15rem !important;
  border-radius: var(--radius-pill);
  color: #fff;
  background: var(--accent);
  font-weight: 600;
  transition: background-color var(--dur-2) var(--ease-soft), transform var(--dur-2) var(--ease-spring);
}

.site-header .nav-cta::after { content: none; }
.site-header .nav-cta:hover { background: var(--accent-hover); transform: translateY(-1px); }

.navbar-toggler {
  border-color: var(--border-strong);
  border-radius: var(--radius-xs);
}

/* The bars are drawn as a mask filled with the current ink, so the hamburger
   is dark on the cream header and light on the black one. As a background
   image its colour would have been baked into the data URI. */
.navbar-toggler-icon {
  background-image: none;
  background-color: currentColor;
  color: var(--text);
  mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3E%3Cpath stroke='%23000' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3E%3C/svg%3E");
  mask-repeat: no-repeat;
  mask-position: center;
  mask-size: 100%;
}

.nav-icons { display: flex; align-items: center; gap: .3rem; margin-inline-start: .5rem; }
.theme-form, .language-form { margin: 0; }

.theme-button, .language-button {
  display: grid;
  place-items: center;
  min-width: 38px;
  height: 38px;
  padding: 0 .6rem;
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-pill);
  color: var(--text);
  background: transparent;
  font-family: var(--font-body);
  font-size: var(--step--1);
  font-weight: 600;
  line-height: 1;
  cursor: pointer;
  transition:
    background-color var(--dur-2) var(--ease-soft),
    border-color var(--dur-2) var(--ease-soft),
    transform var(--dur-2) var(--ease-spring);
}

.theme-button:hover, .language-button:hover,
.theme-button:focus-visible, .language-button:focus-visible {
  background: var(--surface-sunken);
  border-color: var(--accent);
  transform: translateY(-1px);
}

.theme-button svg { width: 17px; height: 17px; }
.theme-button .icon-sun { display: none; }
:root[data-theme="dark"] .theme-button .icon-sun { display: block; }
:root[data-theme="dark"] .theme-button .icon-moon { display: none; }

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .theme-button .icon-sun { display: block; }
  :root:not([data-theme="light"]) .theme-button .icon-moon { display: none; }
}

.nav-inquiry { position: relative; }

.inquiry-badge {
  display: inline-grid;
  place-items: center;
  min-width: 1.3rem;
  height: 1.3rem;
  margin-inline-start: .4rem;
  padding: 0 .35rem;
  border-radius: var(--radius-pill);
  color: #fff;
  background: var(--accent);
  font-size: .7rem;
  font-weight: 700;
  animation: pop-in var(--dur-3) var(--ease-spring) both;
}

.nav-signout { display: flex; align-items: center; padding: .5rem .8rem; margin: 0; }
/* Reads as one of the nav links beside it. It was white from when the header was dark,
   and on the light header it all but disappeared. */
.nav-signout .link-button { color: var(--text-muted); font-weight: 500; text-decoration: none; }
.nav-signout .link-button:hover { color: var(--danger); }

/* ============================ Hero ====================================== */
.hero-section {
  position: relative;
  display: grid;
  align-items: center;
  overflow: hidden;
  min-height: min(88vh, 860px);
  padding-top: var(--header-h);
  color: #fff;
  background: #07111d;
  isolation: isolate;
}

.hero-section::after {
  content: "";
  position: absolute;
  z-index: -1;
  inset: 0;
  background: linear-gradient(90deg, rgba(5, 12, 22, .92) 0%, rgba(5, 12, 22, .74) 36%, rgba(5, 12, 22, .2) 67%, rgba(5, 12, 22, .08) 100%);
  pointer-events: none;
}

.hero-background {
  position: absolute;
  z-index: -2;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
}

.hero-grid {
  position: relative;
  z-index: 1;
  display: grid;
  /* Copy, then the photograph. The figures sit on top of the photograph's outer
     corner rather than taking a column of their own, which is what keeps the
     headline as wide as it is. */
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.02fr);
  gap: clamp(2rem, 5vw, 4rem);
  align-items: center;
  padding-block: clamp(3rem, 7vw, 5.5rem);
}

.hero-media {
  position: relative;
  display: grid;
  justify-items: end;
  min-width: 0;
}

.hero-copy h1 {
  margin: var(--space-4) 0 var(--space-5);
  /* A step below the display size. At the full step this headline takes three
     lines in the hero's column and the picture is pushed off the first screen. */
  font-size: clamp(2.5rem, 1.5rem + 3.1vw, 4.1rem);
  color: #fff;
  letter-spacing: -.035em;
  text-shadow: 0 2px 24px rgba(0, 0, 0, .28);
}

/* One clipping box per word, so a word rising into the first line cannot be seen
   travelling across the second. A single box around the whole heading clips only
   at its own edges and lets exactly that happen. */
.hero-word {
  display: inline-block;
  overflow: hidden;
  /* Room for descenders, taken back out of the layout so the leading is unchanged. */
  padding-bottom: .14em;
  margin-bottom: -.14em;
  vertical-align: bottom;
}

.hero-lede { max-width: 46ch; color: rgba(255, 255, 255, .78); font-size: var(--step-1); font-weight: 400; }
.hero-actions { display: flex; flex-wrap: wrap; gap: .8rem; margin-top: var(--space-6); }
.hero-section .btn-outline-navy { --btn-fg: #fff; --btn-line: rgba(255, 255, 255, .55); }

/* The figures ride the outer corner of the photograph as a raised card, so the
   eye meets the claim and the evidence together. Absolute only where there is
   room for it -- below the breakpoint it returns to the flow. */
.hero-panel {
  position: relative;
  z-index: 2;
  display: grid;
  overflow: hidden;
  min-width: 15rem;
  border: 1px solid rgba(255, 255, 255, .15);
  border-radius: var(--radius-lg);
  background: rgba(7, 17, 29, .82);
  box-shadow: 0 24px 55px rgba(0, 0, 0, .3);
  backdrop-filter: blur(12px);
}

.hero-panel div {
  display: grid;
  gap: .2rem;
  padding: 1.25rem 1.6rem;
  border-bottom: 1px solid var(--border-hair);
  transition: background-color var(--dur-2) var(--ease-soft);
}

.hero-panel div:last-child { border-bottom: 0; }
.hero-panel div:hover { background: rgba(255, 255, 255, .07); }

.hero-panel strong {
  color: var(--accent-text);
  font-family: var(--font-display);
  font-size: var(--step-4);
  font-weight: 600;
  line-height: 1;
  letter-spacing: -.03em;
  font-variant-numeric: tabular-nums;
}

.hero-panel span { color: rgba(255, 255, 255, .68); font-size: var(--step--1); }

.scroll-cue {
  position: absolute;
  z-index: 1;
  inset-inline-start: 50%;
  bottom: 1.75rem;
  width: 22px;
  height: 36px;
  margin-inline-start: -11px;
  border: 1px solid rgba(255, 255, 255, .3);
  border-radius: var(--radius-pill);
}

.scroll-cue::after {
  content: "";
  position: absolute;
  inset-inline-start: 50%;
  top: 7px;
  width: 3px;
  height: 7px;
  margin-inline-start: -1.5px;
  border-radius: var(--radius-pill);
  background: var(--ember-400);
  animation: scroll-cue 2s var(--ease-soft) infinite;
}

/* ---- Marquee ----------------------------------------------------------- */
.marquee {
  overflow: hidden;
  padding-block: 1.1rem;
  border-block: 1px solid var(--border-hair);
  background: var(--surface-raised);
  mask-image: linear-gradient(90deg, transparent, #000 3rem, #000 calc(100% - 3rem), transparent);
}

.marquee-track {
  display: flex;
  align-items: center;
  gap: 3.5rem;
  width: max-content;
  margin: 0;
  /* Clears the edge fade, so the first item is legible when the loop is
     stopped for reduced motion. */
  padding: 0 3.5rem;
  list-style: none;
}

.marquee-track.is-looping { animation: marquee-track 42s linear infinite; }
.marquee:hover .marquee-track.is-looping { animation-play-state: paused; }
[dir="rtl"] .marquee-track.is-looping { animation-direction: reverse; }

.marquee-track li {
  display: flex;
  align-items: center;
  gap: 3.5rem;
  color: var(--text-subtle);
  font-family: var(--font-display);
  font-size: var(--step-1);
  font-weight: 400;
  letter-spacing: -.02em;
  white-space: nowrap;
}

.marquee-track li::after {
  content: "";
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--accent);
}

/* ============================ Cards ===================================== */
/* Photograph on its own plate, then the name under it. The old card laid white
   type over the picture behind a dark gradient, which meant every product shot
   was half-covered by the thing naming it and could only ever be shown cropped.
   Given its own plate the product is shown whole, and the name is read on the
   page rather than on the bottle. */
.category-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 1rem;
}

.category-card {
  display: grid;
  grid-template-rows: auto 1fr;
  min-width: 0;
  overflow: hidden;
  border: 1px solid var(--border-hair);
  border-radius: var(--radius);
  color: var(--text);
  background: var(--surface-raised);
  text-decoration: none;
  transition:
    transform var(--dur-2) var(--ease-out-expo),
    border-color var(--dur-2) var(--ease-soft),
    box-shadow var(--dur-2) var(--ease-soft);
}

.category-card:hover,
.category-card:focus-visible {
  transform: translateY(-4px);
  border-color: var(--border-strong);
  box-shadow: var(--shadow);
}

.category-card img {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 1;
  object-fit: contain;
  background: var(--surface-plate);
  transition: transform var(--dur-4) var(--ease-out-expo);
}


.category-card:hover img { transform: scale(1.03); }

.category-card > div { padding: .95rem 1.05rem 1.15rem; }
.category-card h3 { margin: 0 0 .15rem; color: var(--text); font-size: var(--step-0); letter-spacing: -.01em; }
.category-card span { color: var(--text-muted); font-size: var(--step--1); }

/* The arrow the old card revealed on hover has no room on a plate this size and
   nothing left to say: the whole tile is the link. */
.category-card .go { display: none; }

@media (min-width: 1200px) {
  .category-grid { grid-template-columns: repeat(6, minmax(0, 1fr)); }
}

/* ---- The strip of categories under the hero ---------------------------- */
.category-strip {
  border-block: 1px solid var(--border-hair);
  background: var(--surface-raised);
}

.category-strip + .section { padding-top: var(--space-7); }

.category-strip ul {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: 1fr;
  /* Block margins only. A blanket "margin: 0" is more specific than the
     margin-inline: auto that .container centres itself with, and pinned the
     whole strip to the left edge of the screen. */
  margin-block: 0;
  padding: 0;
  list-style: none;
  /* One row that scrolls sideways rather than wrapping into a ragged second
     line on a narrow screen. */
  overflow-x: auto;
  scrollbar-width: none;
}

.category-strip ul::-webkit-scrollbar { display: none; }

.category-strip li + li { border-inline-start: 1px solid var(--border-hair); }

.category-strip a {
  display: grid;
  justify-items: center;
  gap: .5rem;
  min-width: 8.5rem;
  padding: 1rem .75rem;
  color: var(--text-muted);
  font-size: var(--step--1);
  font-weight: 600;
  text-align: center;
  text-decoration: none;
  transition: color var(--dur-2) var(--ease-soft), background-color var(--dur-2) var(--ease-soft);
}

.category-strip a:hover, .category-strip a:focus-visible {
  color: var(--accent-text);
  background: var(--surface-sunken);
}

.category-strip img {
  width: 58px;
  height: 58px;
  object-fit: contain;
  padding: 4px;
  border-radius: var(--radius-sm);
  background: var(--surface-plate);
  transition: transform var(--dur-2) var(--ease-spring);
}

/* Drawn on clear ground, so it needs no plate: it stands on the band itself and
   the same file reads on the cream one and the dark one. The plate the earlier
   set needed was what put a lit square into every dark-mode row. */
.category-strip img.category-icon {
  width: 58px;
  height: 58px;
  padding: 0;
  border-radius: 0;
  background: none;
}

.category-strip a:hover img { transform: translateY(-2px) scale(1.06); }


[dir="rtl"] .category-card .go { transform: scale(.8) scaleX(-1); }
[dir="rtl"] .category-card:hover .go, [dir="rtl"] .category-card:focus-visible .go { transform: scale(1) scaleX(-1); }

/* ---- Product card ---- */
/* Two across on the narrowest phone, more as the screen allows. Each card asks for about 14rem
   and never for more than half the row, so a phone always gets two, a tablet three, a laptop
   four. auto-fill keeps a lone search result card-sized instead of stretched across the page. */
.product-grid {
  --card-gap: clamp(.65rem, 1.6vw, 1.25rem);
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(14rem, calc(50% - var(--card-gap) / 2)), 1fr));
  gap: var(--card-gap);
}

/* The catalogue is shot on one warm seamless sweep. The images arrive padded with the sweep's
   own colour (ImageUrls.Padded), so each product stands on an unbroken backdrop that runs to
   the card's edges; this is the same colour, shown while the picture loads. */
.product-card {
  --sweep: #e5c29b;
  --sweep-light: #f2d9bb;
  --sweep-deep: #d7b085;
  --glass: rgba(255, 255, 255, .74);
  --glass-edge: rgba(255, 255, 255, .65);
  --cart: #b84a0e;
  --cart-deep: #9a3d0a;
  container: product-card / inline-size;
  position: relative;
  isolation: isolate;
  display: flex;
  min-width: 0;
  flex-direction: column;
  overflow: hidden;
  border: 1px solid var(--border-hair);
  border-radius: var(--radius-lg);
  background: var(--surface-raised);
  box-shadow: var(--shadow-xs);
  transition:
    transform var(--dur-3) var(--ease-out-expo),
    box-shadow var(--dur-3) var(--ease-soft),
    border-color var(--dur-2) var(--ease-soft);
}

/* Keyboard focus lands on the title link, which covers the card, so the ring goes round the card. */
.product-card:has(.product-title a:focus-visible) { outline: 3px solid var(--accent); outline-offset: 3px; }

.product-media {
  position: relative;
  /* 3:4, the shape most of the catalogue is photographed in, so most pictures fill it exactly. */
  aspect-ratio: 3 / 4;
  overflow: hidden;
  background: radial-gradient(130% 95% at 50% 28%, var(--sweep-light) 0%, var(--sweep) 52%, var(--sweep-deep) 100%);
}

.product-media img {
  display: block;
  width: 100%;
  height: 100%;
  /* Contain, not cover: a picture that did not come padded still shows whole. Padded ones are
     already this shape, so contain and cover draw them identically. */
  object-fit: contain;
  transform-origin: 50% 62%;
  transition: transform var(--dur-5) var(--ease-out-expo);
}

/* A soft studio light that follows the pointer, laid over the sweep on hover. */
.product-media::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
  background: radial-gradient(circle at var(--spot-x, 50%) var(--spot-y, 32%), rgba(255, 255, 255, .55), transparent 52%);
  opacity: 0;
  mix-blend-mode: soft-light;
  pointer-events: none;
  transition: opacity var(--dur-3) var(--ease-soft);
}

/* The floor of the sweep darkens a touch toward the card body, which seats the product. */
.product-media::after {
  content: "";
  position: absolute;
  inset: auto 0 0;
  z-index: 1;
  height: 30%;
  background: linear-gradient(to top, rgba(60, 35, 12, .14), transparent);
  pointer-events: none;
}

/* Glass: the badge and the heart sit on the photograph, so they blur what is behind them
   rather than covering it with a flat chip. */
.product-badge,
.product-fav-btn {
  border: 1px solid var(--glass-edge);
  background: var(--glass);
  -webkit-backdrop-filter: blur(10px) saturate(1.5);
  backdrop-filter: blur(10px) saturate(1.5);
  box-shadow: 0 2px 12px rgba(40, 24, 8, .1);
  color: #111820;
}

.product-badge {
  position: absolute;
  z-index: 2;
  inset-block-start: .6rem;
  inset-inline-start: .6rem;
  display: inline-flex;
  max-width: calc(100% - 4.25rem);
  align-items: center;
  gap: .25rem;
  overflow: hidden;
  padding: .28rem .6rem .28rem .45rem;
  border-radius: var(--radius-pill);
  font-size: var(--step--2);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.product-badge svg { flex-shrink: 0; width: .85rem; height: .85rem; fill: #2f7fa3; }

.product-fav { position: absolute; z-index: 2; inset-block-start: .5rem; inset-inline-end: .5rem; margin: 0; }

.product-fav-btn {
  display: grid;
  width: 2.5rem;
  height: 2.5rem;
  place-items: center;
  padding: 0;
  border-radius: 50%;
  cursor: pointer;
  transition: transform var(--dur-2) var(--ease-spring), color var(--dur-2) var(--ease-soft), background-color var(--dur-2) var(--ease-soft);
}

a.product-fav-btn { position: absolute; }

.product-fav-btn svg {
  width: 1.2rem;
  height: 1.2rem;
  fill: transparent;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linejoin: round;
  transition: fill var(--dur-2) var(--ease-soft);
}

.product-fav-btn:hover, .product-fav-btn:focus-visible { color: var(--ember-600); background: rgba(255, 255, 255, .92); }
.product-fav-btn:focus-visible { outline: 3px solid var(--accent); outline-offset: 2px; }
.product-fav-btn[aria-pressed="true"] { color: #d6402b; }
.product-fav-btn[aria-pressed="true"] svg { fill: currentColor; }
.product-fav-btn.is-popping svg { animation: heart-pop 460ms var(--ease-spring); }

@keyframes heart-pop {
  0% { transform: scale(1); }
  30% { transform: scale(1.38); }
  60% { transform: scale(.88); }
  100% { transform: scale(1); }
}

.product-body { display: flex; flex: 1; flex-direction: column; gap: .3rem; padding: .85rem .95rem .95rem; }

.product-category {
  overflow: hidden;
  margin: 0;
  color: var(--accent-text);
  font-size: var(--step--2);
  font-weight: 600;
  letter-spacing: .12em;
  text-overflow: ellipsis;
  text-transform: uppercase;
  white-space: nowrap;
}

/* Two lines, always reserved, so the footers of a row of cards line up. */
.product-title {
  display: -webkit-box;
  overflow: hidden;
  min-height: 2.6em;
  margin: 0;
  font-size: var(--step-0);
  font-weight: 650;
  line-height: 1.3;
  letter-spacing: -.01em;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
}

.product-title a { color: var(--text); text-decoration: none; }
.product-title a:focus-visible { outline: none; }

/* The title's link covers the whole card, so the card is one big target. */
.product-title a::after { content: ""; position: absolute; inset: 0; z-index: 1; }

.product-spec { overflow: hidden; margin: 0; color: var(--text-muted); font-size: var(--step--1); text-overflow: ellipsis; white-space: nowrap; }

.product-foot { display: flex; align-items: center; justify-content: space-between; gap: .5rem; margin-top: auto; padding-top: .55rem; }

/* The works' mould reference: buyers quote it on orders, so it reads as an identifier. */
.product-code {
  overflow: hidden;
  min-width: 0;
  padding: .28rem .5rem;
  border-radius: var(--radius-xs);
  background: var(--surface-sunken);
  color: var(--text);
  font-family: var(--font-mono);
  font-size: var(--step--2);
  font-weight: 600;
  letter-spacing: -.02em;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.product-cart { position: relative; z-index: 2; flex-shrink: 0; margin: 0 0 0 auto; margin-inline-start: auto; }

.product-cart-btn {
  position: relative;
  display: inline-flex;
  height: 2.5rem;
  align-items: center;
  gap: .4rem;
  padding-inline: .85rem 1rem;
  border: 0;
  border-radius: var(--radius-pill);
  background: linear-gradient(135deg, var(--cart), var(--cart-deep));
  box-shadow: 0 6px 16px rgba(184, 74, 14, .26);
  color: #fff;
  font-family: inherit;
  font-size: var(--step--1);
  font-weight: 700;
  white-space: nowrap;
  cursor: pointer;
  transition: transform var(--dur-2) var(--ease-spring), box-shadow var(--dur-2) var(--ease-soft), filter var(--dur-2) var(--ease-soft), background var(--dur-3) var(--ease-soft);
}

.product-cart-btn svg { flex-shrink: 0; width: 1.2rem; height: 1.2rem; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.product-cart-btn .icon-check { display: none; }
.product-cart-btn:hover { filter: brightness(1.08); box-shadow: 0 10px 26px rgba(184, 74, 14, .36); transform: translateY(-1px); }
.product-cart-btn:active { transform: scale(.94); }
.product-cart-btn:focus-visible { outline: 3px solid var(--accent); outline-offset: 2px; }
.product-cart-btn[disabled] { cursor: progress; }

/* Just added: green, a tick, and a ring of light that spreads once. */
.product-cart-btn.is-added { background: linear-gradient(135deg, #17805a, #0f6446); box-shadow: 0 6px 18px rgba(16, 113, 74, .32); }
.product-cart-btn.is-added .icon-bag { display: none; }
.product-cart-btn.is-added .icon-check { display: block; animation: tick-in 380ms var(--ease-spring); }
.product-cart-btn.is-added::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  box-shadow: 0 0 0 0 rgba(16, 113, 74, .45);
  animation: ring-out 700ms var(--ease-out-expo);
  pointer-events: none;
}

@keyframes tick-in { from { transform: scale(.3) rotate(-25deg); opacity: 0; } to { transform: none; opacity: 1; } }
@keyframes ring-out { to { box-shadow: 0 0 0 12px rgba(16, 113, 74, 0); } }

/* Hover is for a mouse. On a touch screen the same rules would stick after a tap. */
@media (hover: hover) and (pointer: fine) {
  .product-card:hover { transform: translateY(-6px); border-color: transparent; box-shadow: var(--shadow-lg); }
  .product-card:hover .product-media img { transform: scale(1.06) translateY(-1.5%); }
  .product-card:hover .product-media::before { opacity: 1; }
}

/* A press on a touch screen gives way a little, so the tap is felt. */
@media (hover: none) {
  .product-card:active { transform: scale(.985); }
}

/* Fingers, not a mouse pointer: the heart grows to a full 44px target. */
@media (pointer: coarse) {
  .product-fav-btn { width: 2.75rem; height: 2.75rem; }
  .product-cart-btn { height: 2.75rem; }
}

/* A narrow card -- two across a phone -- keeps the bag as an icon and tightens the text.
   The label stays in the button for screen readers. */
@container product-card (max-width: 14.5rem) {
  .product-body { padding: .7rem .75rem .8rem; }
  .product-title { font-size: var(--step--1); }
  .product-cart-btn { width: 2.5rem; justify-content: center; padding: 0; }
  .product-cart-label {
    position: absolute;
    overflow: hidden;
    width: 1px;
    height: 1px;
    clip: rect(0 0 0 0);
    white-space: nowrap;
  }
}

@container product-card (max-width: 11rem) {
  .product-badge { font-size: .62rem; }
  .product-code { font-size: .62rem; padding-inline: .35rem; }
}

@media (prefers-reduced-motion: reduce) {
  .product-card, .product-media img, .product-fav-btn, .product-cart-btn { transition: none; }
  .product-card:hover, .product-card:active, .product-card:hover .product-media img { transform: none; }
  .product-fav-btn.is-popping svg, .product-cart-btn.is-added .icon-check, .product-cart-btn.is-added::after { animation: none; }
}

/* The product page's own heart. */
.detail-fav { display: inline-flex; align-items: center; gap: .45rem; }
.detail-fav svg { width: 1.15rem; height: 1.15rem; fill: transparent; stroke: currentColor; stroke-width: 2; stroke-linejoin: round; }
.detail-fav[aria-pressed="true"] svg { fill: #d6402b; stroke: #d6402b; }
.detail-fav.is-popping svg { animation: heart-pop 460ms var(--ease-spring); }

.inquiry-add { margin-top: .9rem; }

/* Specification chips, as the inquiry list, the checkout and the mould screens show them. */
.product-meta { display: flex; flex-wrap: wrap; gap: .35rem; margin-top: auto; color: var(--text-muted); font-size: var(--step--2); }
.product-meta span { padding: .28rem .6rem; border: 1px solid var(--border); border-radius: var(--radius-pill); }
.product-meta .product-code { border-color: transparent; background: var(--surface-sunken); color: var(--text); font-family: var(--font-mono); font-weight: 600; letter-spacing: -.02em; }

/* A short note after an action taken in place, with a way to the result. */
.site-toast {
  position: fixed;
  z-index: 1080;
  inset-block-end: max(1rem, env(safe-area-inset-bottom));
  inset-inline: 50% auto;
  display: flex;
  max-width: min(32rem, calc(100vw - 2rem));
  align-items: center;
  gap: .9rem;
  padding: .8rem .9rem .8rem 1.1rem;
  border-radius: var(--radius);
  background: var(--navy-800);
  box-shadow: var(--shadow-lg);
  color: #f2efe9;
  font-weight: 600;
  transform: translate(-50%, 140%);
  transition: transform var(--dur-3) var(--ease-out-expo);
}
[dir="rtl"] .site-toast { transform: translate(50%, 140%); }
.site-toast.is-shown { transform: translate(-50%, 0); }
[dir="rtl"] .site-toast.is-shown { transform: translate(50%, 0); }
.site-toast a { flex-shrink: 0; padding: .4rem .8rem; border-radius: var(--radius-pill); background: rgba(255, 255, 255, .12); color: #fff; text-decoration: none; }
.site-toast a:hover, .site-toast a:focus-visible { background: rgba(255, 255, 255, .22); }
@media (prefers-reduced-motion: reduce) { .site-toast { transition: none; } }

/* The inquiry count in the header gives a small jump when it changes. */
.inquiry-badge.is-bumped { animation: badge-bump 520ms var(--ease-spring); }
@keyframes badge-bump { 30% { transform: scale(1.45); } 100% { transform: none; } }
@media (prefers-reduced-motion: reduce) { .inquiry-badge.is-bumped { animation: none; } }

/* ---- News ---- */
.news-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 1.5rem; }

.news-card {
  display: flex;
  flex-direction: column;
  overflow: hidden;
  border: 1px solid var(--border-hair);
  border-radius: var(--radius-lg);
  background: var(--surface-raised);
  transition: transform var(--dur-3) var(--ease-out-expo), box-shadow var(--dur-3) var(--ease-soft);
}

.news-card:hover { transform: translateY(-5px); box-shadow: var(--shadow); }
.news-card > img { width: 100%; aspect-ratio: 1.6; object-fit: cover; transition: transform var(--dur-5) var(--ease-out-expo); }
.news-card:hover > img { transform: scale(1.04); }
.news-card > div { display: flex; flex: 1; flex-direction: column; padding: 1.5rem; }
.news-card time, .article-page time { color: var(--accent-text); font-size: var(--step--1); font-weight: 600; }
.news-card h2 { margin: .55rem 0; font-size: var(--step-2); }
.news-card h2 a { color: var(--text); text-decoration: none; }
.news-card h2 a:hover { color: var(--accent-text); }
.news-card p { display: -webkit-box; overflow: hidden; margin: 0; -webkit-line-clamp: 3; -webkit-box-orient: vertical; color: var(--text-muted); }

.article-page h1 { margin: .8rem 0 2rem; }
.article-image { width: 100%; max-height: 540px; object-fit: cover; border-radius: var(--radius-lg); }
.article-copy { margin-top: 2rem; font-size: var(--step-1); font-weight: 300; white-space: pre-line; }

/* ============================ Page hero ================================= */
/* The band every inner page opens with. It was navy, which meant the site had
   two grounds and the header had to survive both; it is the page's own ground
   now, separated from the content below by a rule rather than by a colour. */
.page-hero {
  position: relative;
  overflow: hidden;
  padding-block: calc(var(--header-h) + 3.25rem) 3.25rem;
  border-bottom: 1px solid var(--border-hair);
  color: var(--text);
  background: var(--surface);
  isolation: isolate;
}

.page-hero .container { position: relative; z-index: 1; }
.page-hero h1 { margin: .7rem 0 1rem; font-size: var(--step-5); }
.page-hero p { max-width: 62ch; margin: 0; color: var(--text-subtle); font-size: var(--step-1); font-weight: 400; }
.page-hero.compact { padding-block: calc(var(--header-h) + 2.75rem) 2.75rem; }

.page-hero .back-link { color: var(--text-muted); }
.page-hero .back-link:hover { color: var(--accent-text); }

/* ============================ Catalogue ================================= */
.filter-panel {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: .7rem;
  padding: 0;
  border: 0;
  background: none;
}

.filter-panel .form-control, .filter-panel .form-select {
  min-height: 46px;
  border-radius: var(--radius-pill);
  background-color: var(--surface-raised);
}

.filter-panel > * { flex: 1 1 180px; min-width: 0; }
.filter-panel > .filter-search { flex: 2 1 260px; }
.filter-panel label { display: block; margin-bottom: .3rem; color: var(--text-muted); font-size: var(--step--2); font-weight: 600; letter-spacing: .1em; text-transform: uppercase; }
.filter-panel .btn { flex: 0 0 auto; }

.result-summary { margin: var(--space-6) 0 var(--space-5); color: var(--text-muted); font-weight: 500; }
.result-summary strong { color: var(--text); }

.empty-state {
  padding: 5rem 1.5rem;
  border: 1px dashed var(--border-strong);
  border-radius: var(--radius-lg);
  background: var(--surface-raised);
  text-align: center;
}

.pagination-wrap { display: flex; justify-content: center; margin-top: var(--space-7); }
.pagination { gap: .35rem; }

.pagination .page-link {
  min-width: 42px;
  border: 1px solid var(--border);
  border-radius: var(--radius-pill) !important;
  color: var(--text);
  background: var(--surface-raised);
  font-size: var(--step--1);
  font-weight: 600;
  text-align: center;
  transition: transform var(--dur-2) var(--ease-spring), background-color var(--dur-2) var(--ease-soft), color var(--dur-2) var(--ease-soft);
}

.pagination .page-link:hover { transform: translateY(-2px); color: var(--accent-text); background: var(--surface-raised); }
.pagination .page-item.active .page-link { color: #fff; border-color: var(--brand); background: var(--brand); }
.pagination .page-item.disabled .page-link { color: var(--text-muted); background: transparent; }

/* ============================ Product detail ============================ */
.product-detail { min-height: 60vh; }
.detail-grid, .content-grid, .form-layout { display: grid; grid-template-columns: minmax(0, 1fr) minmax(320px, .85fr); gap: clamp(2.5rem, 6vw, 5.5rem); }
.detail-grid { align-items: start; }

.detail-image {
  min-width: 0;
}

.detail-image > img {
  display: block;
  width: 100%;
  aspect-ratio: 1 / 1;
  object-fit: contain;
  padding: clamp(1rem, 4vw, 2rem);
  border-radius: var(--radius-xl);
  background: var(--surface-plate);
}
.detail-grid h1 { margin: 1rem 0; font-size: var(--step-4); }

.spec-list { display: grid; grid-template-columns: 1fr 1fr; gap: 0; margin: var(--space-6) 0; border-block: 1px solid var(--border); }
.spec-list div { padding: .95rem 0; border-bottom: 1px solid var(--border-hair); }
.spec-list dt { color: var(--text-muted); font-size: var(--step--2); font-weight: 600; letter-spacing: .1em; text-transform: uppercase; }
.spec-list dd { margin: .2rem 0 0; font-weight: 600; }

.detail-actions { display: flex; flex-wrap: wrap; align-items: center; gap: .8rem; margin-top: var(--space-6); }
.detail-inquiry { display: flex; gap: .6rem; margin: 0; }
.detail-inquiry .form-control { width: 7.5rem; }

.detail-gallery { display: flex; flex-wrap: wrap; gap: .6rem; margin: .9rem 0 0; padding: 0; list-style: none; }

.detail-gallery img {
  width: 86px;
  height: 86px;
  object-fit: contain;
  padding: .35rem;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface-plate);
  transition: transform var(--dur-2) var(--ease-spring), border-color var(--dur-2) var(--ease-soft);
}

.detail-gallery a:hover img { transform: translateY(-3px) scale(1.03); border-color: var(--accent); }

/* ============================ Inquiry list ============================== */
.quote-layout { display: grid; grid-template-columns: minmax(0, 1.55fr) minmax(320px, .85fr); gap: clamp(2rem, 4vw, 3.5rem); align-items: start; }
.quote-lines { display: grid; gap: .85rem; }

.quote-line {
  display: grid;
  grid-template-columns: 104px minmax(0, 1fr) auto;
  gap: 1.2rem;
  align-items: center;
  padding: 1rem;
  border: 1px solid var(--border-hair);
  border-radius: var(--radius);
  background: var(--surface-raised);
  transition: box-shadow var(--dur-2) var(--ease-soft);
}

.quote-line:hover { box-shadow: var(--shadow-sm); }
.quote-line-image { display: block; overflow: hidden; width: 104px; height: 104px; border-radius: var(--radius-sm); background: var(--surface-plate); }
.quote-line-image img { width: 100%; height: 100%; object-fit: contain; padding: .4rem; }
.quote-line-body h3 { margin: .35rem 0 .55rem; font-size: var(--step-1); }
.quote-line-body h3 a { color: var(--text); text-decoration: none; }
.quote-line-body h3 a:hover { color: var(--accent-text); }
.quote-line-actions { display: grid; justify-items: end; gap: .5rem; }
.quote-qty-form { display: flex; gap: .4rem; margin: 0; }
.quote-qty-form .form-control { width: 7rem; min-height: 42px; }
.quote-clear { justify-self: start; margin-top: .35rem; }

.quote-receipt {
  display: grid;
  gap: .35rem;
  margin-bottom: var(--space-6);
  padding: 1.6rem;
  border: 1px solid var(--border-hair);
  border-inline-start: 4px solid var(--accent);
  border-radius: var(--radius);
  background: var(--surface-raised);
}

.quote-receipt span { color: var(--text-muted); font-size: var(--step--2); font-weight: 600; letter-spacing: .1em; text-transform: uppercase; }
.quote-receipt strong { font-family: var(--font-display); font-size: var(--step-3); letter-spacing: -.03em; }
.quote-items-heading { margin: var(--space-7) 0 1rem; font-size: var(--step-2); }
.quote-delete { margin-top: var(--space-5); }

/* ============================ Orders ==================================== */
.or-place-order { margin-top: 1rem; }
.order-cards { display: grid; grid-template-columns: repeat(auto-fill, minmax(270px, 1fr)); gap: 1rem; }

.order-card {
  display: grid;
  gap: .4rem;
  padding: 1.5rem;
  border: 1px solid var(--border-hair);
  border-radius: var(--radius);
  color: var(--text);
  background: var(--surface-raised);
  text-decoration: none;
  transition: transform var(--dur-2) var(--ease-out-expo), box-shadow var(--dur-2) var(--ease-soft);
}

.order-card:hover { transform: translateY(-4px); box-shadow: var(--shadow); color: var(--text); }
.order-card header { display: flex; align-items: center; justify-content: space-between; gap: .6rem; }
.order-card p { margin: 0; color: var(--text-muted); font-size: var(--step--1); }
.order-card-total strong { color: var(--text); font-size: var(--step-1); }
.order-card time { color: var(--text-muted); font-size: var(--step--2); }

.order-lines { display: grid; gap: .5rem; margin-bottom: var(--space-6); }
.order-line { display: grid; align-items: center; grid-template-columns: 1fr auto auto; gap: 1rem; padding: .95rem 1.1rem; border: 1px solid var(--border-hair); border-radius: var(--radius-sm); background: var(--surface-raised); }
.order-line small { display: block; color: var(--text-muted); font-size: var(--step--2); }
.order-totals { display: grid; grid-template-columns: 1fr auto; gap: .4rem 1.5rem; max-width: 420px; margin: 0 0 1rem; }
.order-totals dd { margin: 0; text-align: end; }
.order-totals .grand { padding-top: .45rem; border-top: 1px solid var(--border); font-size: var(--step-1); font-weight: 700; }

/* ============================ Forms ===================================== */
.fact-panel, .form-card, .contact-details {
  padding: clamp(1.6rem, 4vw, 2.6rem);
  border: 1px solid var(--border-hair);
  border-radius: var(--radius-lg);
  background: var(--surface-raised);
  box-shadow: var(--shadow-sm);
}

.fact-panel dl { margin: 0; }
.fact-panel dt { color: var(--text-muted); font-size: var(--step--2); font-weight: 600; letter-spacing: .1em; text-transform: uppercase; }
.fact-panel dd { margin: .15rem 0 1.25rem; font-size: var(--step-1); font-weight: 600; }
.fact-panel dd:last-child { margin-bottom: 0; }

.form-card form, .admin-form { display: grid; gap: 1.15rem; }
.form-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 1rem; }
.form-label, .admin-form label { margin: 0 0 .4rem; font-size: var(--step--1); font-weight: 600; }

.form-control, .form-select {
  min-height: 48px;
  padding: .6rem 1rem;
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
  color: var(--text);
  background-color: var(--surface-raised);
  font-family: var(--font-body);
  font-size: var(--step-0);
  transition: border-color var(--dur-2) var(--ease-soft), box-shadow var(--dur-2) var(--ease-soft), background-color var(--dur-2) var(--ease-soft);
}

.form-control:focus, .form-select:focus {
  color: var(--text);
  border-color: var(--accent);
  background-color: var(--surface-raised);
  box-shadow: 0 0 0 4px var(--accent-wash);
}

.form-control::placeholder { color: var(--text-muted); opacity: 1; }
textarea.form-control { min-height: auto; }
.field-validation-error, .field-error { display: block; margin-top: .3rem; color: var(--danger); font-size: var(--step--1); }
.hp-field { position: absolute !important; width: 1px; height: 1px; overflow: hidden; opacity: 0; pointer-events: none; }
.form-actions { display: flex; flex-wrap: wrap; align-items: center; gap: .7rem; }
.form-actions .form-select { width: auto; }
.checkbox-row { display: flex; align-items: center; gap: .55rem; }
.checkbox-row input { accent-color: var(--accent); }

.validation-summary:not(:empty) {
  margin-bottom: 1.3rem;
  padding: 1rem 1.2rem;
  border: 1px solid color-mix(in srgb, var(--danger) 30%, transparent);
  border-radius: var(--radius-sm);
  color: var(--danger);
  background: var(--danger-surface);
  animation: fade-up var(--dur-3) var(--ease-out-expo) both;
}

.validation-summary ul { margin: 0; padding-inline-start: 1.1rem; }

.login-card { max-width: 460px; margin: 0 auto; }
.login-card h1 { margin: .5rem 0 1.5rem; font-size: var(--step-3); }

.alert {
  border: 1px solid transparent;
  border-radius: var(--radius-sm);
  animation: fade-up var(--dur-3) var(--ease-out-expo) both;
}

.alert-success { color: var(--success); border-color: color-mix(in srgb, var(--success) 30%, transparent); background: var(--success-surface); }
.alert-danger { color: var(--danger); border-color: color-mix(in srgb, var(--danger) 30%, transparent); background: var(--danger-surface); }

/* ============================ CTA band ================================== */
.cta-section {
  position: relative;
  overflow: hidden;
  padding-block: clamp(3.5rem, 7vw, 5.5rem);
  color: #fff;
  background: linear-gradient(115deg, var(--ember-600), var(--ember-500) 55%, var(--ember-400));
  isolation: isolate;
}

.cta-section::before {
  content: "";
  position: absolute;
  z-index: -1;
  inset-inline-end: -8%;
  top: -60%;
  width: 46vw;
  height: 46vw;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(255, 255, 255, .3), transparent 62%);
  filter: blur(30px);
  animation: aurora-a 26s var(--ease-soft) infinite;
}

.cta-grid { position: relative; display: flex; align-items: center; justify-content: space-between; gap: 2rem; }
.cta-grid h2 { max-width: 22ch; margin: .5rem 0 0; }
.cta-section .eyebrow { color: rgba(255, 255, 255, .82); }

/* ============================ Footer ==================================== */
.site-footer {
  padding: clamp(3.5rem, 7vw, 5.5rem) 0 1.5rem;
  color: #a8b8c6;
  background: var(--navy-900);
}

.footer-grid { display: grid; grid-template-columns: 1.6fr 1fr 1fr; gap: 3rem; }
.footer-grid > div { display: flex; flex-direction: column; align-items: flex-start; gap: .35rem; }

.footer-brand {
  margin-bottom: .4rem;
  color: #fff;
  font-family: var(--font-display);
  font-size: var(--step-3);
  font-weight: 500;
  letter-spacing: -.04em;
}

.footer-grid h2 { margin-bottom: .5rem; color: #fff; font-family: var(--font-body); font-size: var(--step--2); font-weight: 600; letter-spacing: .16em; text-transform: uppercase; }

.footer-grid a {
  position: relative;
  color: #a8b8c6;
  text-decoration: none;
  transition: color var(--dur-1) var(--ease-soft), padding-inline-start var(--dur-2) var(--ease-out-expo);
}

.footer-grid a:hover { color: #fff; padding-inline-start: .4rem; }
.footer-bottom { margin-top: 3rem; padding-top: 1.3rem; border-top: 1px solid rgba(255, 255, 255, .1); font-size: var(--step--1); }

.message-page-actions { display: flex; flex-wrap: wrap; gap: 12px; margin-bottom: 24px; }
.message-conversation { max-width: 900px; display: grid; gap: 20px; }
.message-conversation > .btn { justify-self: start; }
.message-conversation .message-card { overflow-wrap: anywhere; }
.message-conversation .message-staff { border-inline-start: 4px solid var(--accent-text); }
.message-conversation .form-card form { display: grid; gap: 14px; }
.message-snippet { overflow: hidden; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; }

/* ============================ Admin ===================================== */
.admin-site { min-height: 100vh; background: var(--surface-sunken); }

.admin-header {
  position: fixed;
  z-index: 50;
  inset-block: 0;
  inset-inline-start: 0;
  display: flex;
  width: 252px;
  flex-direction: column;
  padding: 1.5rem 1rem;
  color: #fff;
  background: var(--navy-900);
}

.admin-brand { margin-bottom: 2rem; color: #fff; font-family: var(--font-display); font-size: var(--step-1); font-weight: 600; letter-spacing: -.03em; text-decoration: none; }
.admin-brand span { display: block; color: var(--ember-300); font-family: var(--font-body); font-size: var(--step--2); font-weight: 600; letter-spacing: .14em; text-transform: uppercase; }
.admin-header nav { display: flex; flex: 1; flex-direction: column; gap: .15rem; overflow-y: auto; }

.admin-header nav > a, .admin-header nav button {
  display: block;
  width: 100%;
  padding: .62rem .85rem;
  border: 0;
  border-radius: var(--radius-xs);
  color: #b9c8d5;
  background: transparent;
  font-family: var(--font-body);
  font-size: var(--step--1);
  font-weight: 500;
  text-align: start;
  text-decoration: none;
  transition: color var(--dur-1) var(--ease-soft), background-color var(--dur-1) var(--ease-soft), padding-inline-start var(--dur-2) var(--ease-out-expo);
}

.admin-header nav > a:hover, .admin-header nav button:hover { color: #fff; background: rgba(255, 255, 255, .08); padding-inline-start: 1.1rem; }
.admin-header nav form { margin-top: auto; }
.admin-menu { display: none; }
.admin-lang { margin: -1.25rem 0 1.25rem; }
.admin-lang button {
  padding: .3rem .8rem;
  border: 1px solid rgba(255, 255, 255, .3);
  border-radius: var(--radius-xs);
  color: #fff;
  background: transparent;
  font-family: var(--font-body);
  font-size: var(--step--1);
  font-weight: 600;
  cursor: pointer;
}
.admin-lang button:hover, .admin-lang button:focus-visible { background: rgba(255, 255, 255, .1); }
.admin-main { margin-inline-start: 252px; padding: clamp(1.5rem, 4vw, 3rem); }
/* The way in to stock in / out, first on the dashboard for anyone who may use it. */
.stock-cta { display: grid; gap: .25rem; margin-block: 0 var(--space-6); padding: 1.25rem 1.4rem; border-radius: .75rem; background: #2c7366; color: #fff; text-decoration: none; }
.stock-cta strong { font-size: 1.35rem; }
.stock-cta span { opacity: .9; }
.stock-cta:hover, .stock-cta:focus-visible { filter: brightness(1.08); color: #fff; }
.admin-page-heading { display: flex; align-items: center; justify-content: space-between; gap: 1rem; margin-bottom: var(--space-6); }
.admin-page-heading h1 { margin: 0; font-size: var(--step-3); }
.admin-lead { max-width: 62ch; margin: -1rem 0 1.6rem; color: var(--text-muted); }
.admin-cards { display: grid; gap: 1.5rem; max-width: 1100px; }
.admin-card, .admin-form, .admin-detail { border: 1px solid var(--border-hair); border-radius: var(--radius); background: var(--surface-raised); }
.admin-card { padding: clamp(1.25rem, 3vw, 2rem); }
.admin-card > h2 { margin: 0 0 .35rem; font-size: var(--step-2); }
.admin-card > .form-help { margin-bottom: 1.2rem; }
.admin-card .admin-form { max-width: none; padding: 0; border: 0; background: none; }
.admin-form, .admin-detail { max-width: 980px; padding: 2rem; }
.admin-form fieldset { display: grid; gap: 1rem; padding: 0 0 2rem; border: 0; border-bottom: 1px solid var(--border-hair); }
.admin-form legend { margin-bottom: 1rem; font-family: var(--font-display); font-size: var(--step-1); font-weight: 600; }
.admin-detail dl { display: grid; grid-template-columns: 160px 1fr; gap: .7rem 1.5rem; }
.admin-detail dt { color: var(--text-muted); }
.form-help { margin: 0 0 .3rem; color: var(--text-muted); font-size: var(--step--1); }
.form-preview { width: 150px; height: 150px; object-fit: cover; border-radius: var(--radius-sm); background: var(--surface-plate); }
.admin-site .text-muted { color: var(--text-muted) !important; }

.stat-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 1rem; }

.stat-grid a {
  display: grid;
  padding: 1.7rem;
  border: 1px solid var(--border-hair);
  border-radius: var(--radius);
  color: var(--text);
  background: var(--surface-raised);
  text-decoration: none;
  transition: transform var(--dur-2) var(--ease-out-expo), box-shadow var(--dur-2) var(--ease-soft);
}

.stat-grid a:hover { transform: translateY(-3px); box-shadow: var(--shadow); }
.stat-grid strong { font-family: var(--font-display); font-size: var(--step-4); font-weight: 500; letter-spacing: -.03em; }
.stat-grid span { color: var(--text-muted); font-size: var(--step--1); }

.admin-filter { display: flex; flex-wrap: wrap; max-width: 860px; gap: .6rem; margin-bottom: 1.2rem; }
.admin-filter > * { flex: 1 1 150px; min-width: 0; }
.admin-filter .btn { flex: 0 0 auto; white-space: nowrap; }

.admin-table-wrap { overflow-x: auto; border: 1px solid var(--border-hair); border-radius: var(--radius); background: var(--surface-raised); }

/* Bootstrap paints tables from its own light-mode literals, so the variables are
   pointed at the tokens or every table is a white slab in dark mode. */
.admin-table {
  min-width: 700px;
  margin: 0;
  vertical-align: middle;
  --bs-table-bg: transparent;
  --bs-table-color: var(--text);
  --bs-table-border-color: var(--border-hair);
  --bs-table-hover-bg: var(--surface-sunken);
  --bs-table-hover-color: var(--text);
}

.admin-table th { padding: .9rem 1.1rem; color: var(--text-muted); background: var(--surface-sunken); font-size: var(--step--2); font-weight: 600; letter-spacing: .1em; text-transform: uppercase; }
.admin-table td { padding: .9rem 1.1rem; }
.admin-table td > small { display: block; color: var(--text-muted); }
.admin-table a { color: var(--accent-text); }
.admin-table img { width: 54px; height: 54px; object-fit: cover; border-radius: var(--radius-xs); background: var(--surface-plate); }

/* A flex td is taken out of the table layout entirely; alignment does the job. */
.table-actions { text-align: end; white-space: nowrap; }
.table-actions > * + * { margin-inline-start: .45rem; }

.status-pill { display: inline-flex; padding: .28rem .65rem; border-radius: var(--radius-pill); color: var(--text-muted); background: var(--surface-sunken); font-size: var(--step--2); font-weight: 600; }
.status-pill.live { color: var(--success); background: var(--success-surface); }
.status-pill.draft { color: var(--warning); background: var(--warning-surface); }
.status-pill.machine-running { color: var(--success); background: var(--success-surface); }
.status-pill.machine-idle { color: var(--info); background: var(--info-surface); }
.status-pill.machine-maintenance { color: var(--warning); background: var(--warning-surface); }
.status-pill.machine-fault { color: var(--danger); background: var(--danger-surface); }
.status-pill.order-pending { color: var(--warning); background: var(--warning-surface); }
.status-pill.order-confirmed, .status-pill.order-inproduction { color: var(--info); background: var(--info-surface); }
.status-pill.order-ready, .status-pill.order-delivered { color: var(--success); background: var(--success-surface); }
.status-pill.order-cancelled { color: var(--danger); background: var(--danger-surface); }

.message-list { display: grid; gap: 1rem; }
.message-card { padding: 1.5rem; border: 1px solid var(--border-hair); border-inline-start: 4px solid var(--accent); border-radius: var(--radius-sm); background: var(--surface-raised); box-shadow: var(--shadow-xs); }
.message-card.reviewed { border-inline-start-color: var(--border-strong); opacity: .8; }
.message-card header { display: flex; justify-content: space-between; gap: 1rem; }
.message-card header div { display: grid; }
.message-card header span, .message-card time { color: var(--text-muted); font-size: var(--step--1); }
.pre-line { white-space: pre-line; }

.user-summary { display: flex; flex-wrap: wrap; align-items: center; gap: .6rem 1rem; margin-bottom: 1.5rem; }
.role-pill { display: inline-flex; padding: .28rem .65rem; border-radius: var(--radius-pill); color: var(--text-muted); background: var(--surface-sunken); font-size: var(--step--2); font-weight: 600; }
.role-pill + .role-pill { margin-inline-start: .3rem; }
.role-pill.internal { color: var(--info); background: var(--info-surface); }
.source-pill { display: inline-flex; padding: .12rem .5rem; border-radius: var(--radius-pill); color: var(--text-muted); background: var(--surface-sunken); font-size: .7rem; font-weight: 600; }
.source-pill.direct { color: var(--accent-text); background: var(--warning-surface); }
.account-actions { display: flex; flex-wrap: wrap; gap: .7rem; margin-bottom: .8rem; }

/* The permission grid is the densest thing in the admin area -- 24 checkboxes --
   so it is grouped exactly as the catalogue orders them rather than run as one
   long list. */
.permission-bulk { display: flex; gap: 1rem; margin-bottom: .8rem; }
.permission-groups { display: grid; align-items: start; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: 1.2rem; }
.permission-picker .permission-group { display: block; min-width: 0; padding: 1rem 1.1rem 1.2rem; border: 1px solid var(--border-hair); border-radius: var(--radius-sm); background: var(--surface); }
.permission-picker .permission-group legend { float: none; width: auto; margin: 0 0 .5rem; padding: 0; color: var(--text-muted); font-family: var(--font-body); font-size: var(--step--2); font-weight: 600; letter-spacing: .1em; text-transform: uppercase; }
.permission-picker .permission-item { display: flex; align-items: flex-start; gap: .55rem; margin: 0; padding: .32rem 0; font-size: var(--step--1); font-weight: 400; line-height: 1.4; cursor: pointer; }
.permission-picker .permission-item input { flex: none; width: 1.05rem; height: 1.05rem; margin-top: .18rem; accent-color: var(--accent); }
.permission-picker .permission-item small { display: block; color: var(--text-muted); font-size: .74rem; }
.permission-picker .permission-item.is-locked { color: var(--text-muted); cursor: default; }
.permission-summary, .permission-summary ul { margin: 0; padding: 0; list-style: none; }
.permission-summary { display: grid; align-items: start; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: 1.2rem; }
.permission-summary h3 { margin: 0 0 .4rem; color: var(--text-muted); font-family: var(--font-body); font-size: var(--step--2); font-weight: 600; letter-spacing: .1em; text-transform: uppercase; }
.permission-summary li li { display: flex; flex-wrap: wrap; align-items: center; gap: .4rem; padding: .2rem 0; font-size: var(--step--1); }

/* ---- Operations. The charts are built from sized elements: a CDN script is
   refused by the content security policy, and rendering them server-side means
   they carry the theme, the language and the reading direction with the page. */
.kpi-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)); gap: 1rem; margin-bottom: 1.5rem; }
.kpi { display: grid; gap: .2rem; padding: 1.35rem 1.5rem; border: 1px solid var(--border-hair); border-radius: var(--radius); background: var(--surface-raised); }
.kpi > span { color: var(--text-muted); font-size: var(--step--2); font-weight: 600; letter-spacing: .1em; text-transform: uppercase; }
.kpi > strong { font-family: var(--font-display); font-size: var(--step-4); font-weight: 500; line-height: 1.05; letter-spacing: -.03em; font-variant-numeric: tabular-nums; }
.kpi > strong.kpi-small { font-size: var(--step-2); }
.kpi > small { color: var(--text-muted); font-size: var(--step--1); }
.kpi.danger { border-color: var(--danger); }
.kpi.danger > strong { color: var(--danger); }
.kpi-inline { margin: 0 0 .3rem; font-family: var(--font-display); font-size: var(--step-3); font-weight: 500; }
.trend.up { color: var(--success); }
.trend.down { color: var(--danger); }

.status-strip { display: flex; flex-wrap: wrap; gap: .5rem; margin-bottom: 1.5rem; }
.status-strip a, .status-strip span { display: flex; align-items: baseline; gap: .4rem; padding: .5rem 1rem; border: 1px solid var(--border-hair); border-radius: var(--radius-pill); color: var(--text); background: var(--surface-raised); font-size: var(--step--1); text-decoration: none; transition: transform var(--dur-2) var(--ease-spring), border-color var(--dur-2) var(--ease-soft); }
.status-strip strong { font-weight: 700; }
.status-strip a:hover { transform: translateY(-2px); border-color: var(--accent); }

.operations-layout { max-width: none; }

.chart { display: flex; align-items: flex-end; gap: clamp(3px, 1%, 12px); height: 210px; margin: 0; padding: 0; list-style: none; }
.chart > li { display: flex; flex: 1; min-width: 0; flex-direction: column; justify-content: flex-end; height: 100%; }
.chart-column { display: flex; flex: 1; align-items: flex-end; justify-content: center; }

/* The bar grows from its own baseline as the chart scrolls in. transform-origin
   does the work, so no layout runs during the animation. */
.chart-bar {
  position: relative;
  width: 100%;
  max-width: 54px;
  min-height: 2px;
  margin-inline: auto;
  border-radius: 5px 5px 0 0;
  background: var(--chart-bar);
  transform-origin: 50% 100%;
}

html.js [data-reveal].is-in .chart-bar,
html.js .chart-bar { animation: bar-grow var(--dur-4) var(--ease-out-expo) both; }

@keyframes bar-grow {
  from { transform: scaleY(0); }
  to { transform: scaleY(1); }
}

.chart-reject { position: absolute; inset-block-end: 0; inset-inline: 0; border-radius: 0 0 4px 4px; background: var(--danger); }
.chart-label { padding-top: .45rem; color: var(--text-muted); font-size: .68rem; text-align: center; white-space: nowrap; }
.chart-legend { display: flex; flex-wrap: wrap; align-items: center; gap: .4rem 1rem; margin: .9rem 0 0; color: var(--text-muted); font-size: var(--step--1); }
.chart-key { display: inline-block; width: .75rem; height: .75rem; border-radius: 3px; }
.chart-key.good { background: var(--chart-bar); }
.chart-key.reject { background: var(--danger); }
.chart-empty { padding: 3rem 0; text-align: center; }

.machine-bars { display: grid; gap: .7rem; margin: 0; padding: 0; list-style: none; }
.machine-bars li { display: grid; align-items: center; grid-template-columns: minmax(90px, 25%) 1fr auto; gap: .8rem; }
.machine-bars a { color: var(--text); font-weight: 600; text-decoration: none; }
.machine-bars a small { display: block; color: var(--text-muted); font-weight: 400; font-size: .74rem; }
.machine-bar { height: 10px; border-radius: var(--radius-pill); background: var(--chart-track); overflow: hidden; }
.machine-bar > span { display: block; height: 100%; min-width: 3px; border-radius: var(--radius-pill); background: var(--chart-bar); transform-origin: 0 50%; animation: bar-slide var(--dur-5) var(--ease-out-expo) both; }
[dir="rtl"] .machine-bar > span { transform-origin: 100% 50%; }

@keyframes bar-slide {
  from { transform: scaleX(0); }
  to { transform: scaleX(1); }
}

.alert-list { display: grid; gap: .6rem; margin: 0; padding: 0; list-style: none; }
.alert-list.standalone { margin-top: 1.5rem; }
.alert-list li { display: flex; align-items: flex-start; justify-content: space-between; gap: 1rem; padding: .95rem 1.1rem; border: 1px solid var(--border-hair); border-inline-start: 4px solid var(--info); border-radius: var(--radius-sm); background: var(--surface-raised); }
.alert-list li.severity-warning { border-inline-start-color: var(--warning); }
.alert-list li.severity-critical { border-inline-start-color: var(--danger); }
.alert-list small { display: block; color: var(--text-muted); font-size: var(--step--2); }
.alert-list p { margin: .5rem 0 0; color: var(--text-muted); font-size: var(--step--1); }
.alert-actions { display: flex; flex-wrap: wrap; align-items: center; gap: .5rem; }

.price-rows { display: grid; gap: .7rem; }
.price-row { display: grid; align-items: center; grid-template-columns: 1fr 160px; gap: 1rem; margin: 0; }
.price-row > span { font-weight: 500; }
.price-row small { color: var(--text-muted); font-weight: 400; }
.bar-name { min-width: 0; overflow-wrap: anywhere; font-weight: 600; }
.bar-name small { display: block; color: var(--text-muted); font-weight: 400; font-size: .74rem; }

.gallery-card { max-width: 980px; margin-top: 1.5rem; }
.gallery-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 1rem; margin: 1rem 0; padding: 0; list-style: none; }
.gallery-grid li { display: grid; gap: .5rem; padding: .6rem; border: 1px solid var(--border-hair); border-radius: var(--radius-sm); background: var(--surface); }
.gallery-grid li.is-primary { border-color: var(--success); }
.gallery-grid img { width: 100%; aspect-ratio: 1; object-fit: contain; padding: .45rem; border-radius: var(--radius-xs); background: var(--surface-plate); }
.gallery-actions { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: .4rem; }

.field-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(210px, 1fr)); gap: 1rem; }
.spec-grid { display: grid; grid-template-columns: max-content 1fr; gap: .55rem 1.5rem; margin: 0; }
.spec-grid dt { color: var(--text-muted); }
.spec-grid dd { margin: 0; }
.danger-form { margin-top: 1.5rem; }

/* ============================ Arabic ====================================
   The small-caps treatment on eyebrows, labels and table headers is built for
   Latin. Arabic has no uppercase, and tracking pulls apart letters that are
   meant to join, which is exactly why those captions read as broken. Arabic also
   carries a smaller apparent x-height at the same point size, so the labels need
   a little more of it. */
[dir="rtl"] body { font-family: var(--font-arabic); line-height: 1.9; }
[dir="rtl"] h1, [dir="rtl"] h2, [dir="rtl"] h3, [dir="rtl"] h4 { font-family: var(--font-arabic); font-weight: 700; line-height: 1.4; letter-spacing: normal; }
[dir="rtl"] .footer-brand, [dir="rtl"] .admin-brand, [dir="rtl"] .marquee-track li,
[dir="rtl"] .hero-panel strong, [dir="rtl"] .kpi > strong, [dir="rtl"] .stat-grid strong,
[dir="rtl"] .quote-receipt strong, [dir="rtl"] .kpi-inline { font-family: var(--font-arabic); letter-spacing: normal; }

[dir="rtl"] .eyebrow,
[dir="rtl"] .product-category,
[dir="rtl"] .admin-table th,
[dir="rtl"] .fact-panel dt,
[dir="rtl"] .spec-list dt,
[dir="rtl"] .stat-grid span,
[dir="rtl"] .filter-panel label,
[dir="rtl"] .quote-receipt span,
[dir="rtl"] .footer-grid h2,
[dir="rtl"] .kpi > span,
[dir="rtl"] .permission-picker .permission-group legend,
[dir="rtl"] .permission-summary h3,
[dir="rtl"] .admin-brand span { letter-spacing: normal; text-transform: none; }

[dir="rtl"] .eyebrow { font-size: var(--step--1); }
[dir="rtl"] .product-category { font-size: var(--step--1); }
[dir="rtl"] .admin-table th { font-size: var(--step--1); }
[dir="rtl"] .fact-panel dt, [dir="rtl"] .spec-list dt { font-size: var(--step--1); }
[dir="rtl"] .hero-section::after,
[dir="rtl"] .hero-background { transform: scaleX(-1); }
[dir="rtl"] .back-link > span[aria-hidden="true"] { display: inline-block; transform: scaleX(-1); }

/* ============================ Responsive ================================ */
@media (max-width: 991.98px) {
  .site-header .navbar-collapse {
    margin-top: .75rem;
    padding: 1rem;
    border: 1px solid var(--border);
    border-radius: var(--radius);
    background: var(--surface-raised);
    box-shadow: var(--shadow);
  }

  .site-header .nav-link::after { content: none; }
  .nav-cta { display: inline-block; margin: .5rem 0 0; }
  .nav-icons { margin: .75rem 0 0; }
  .hero-grid, .content-grid, .form-layout, .detail-grid, .quote-layout { grid-template-columns: 1fr; }
  .hero-section { min-height: auto; }
  .hero-media { justify-items: stretch; }
  .hero-panel { width: 100%; }
  .hero-panel { grid-template-columns: repeat(3, 1fr); }
  .hero-panel div { border-bottom: 0; border-inline-end: 1px solid rgba(255, 255, 255, .12); }
  .hero-panel div:last-child { border-inline-end: 0; }
  .scroll-cue { display: none; }
  .category-grid { grid-template-columns: repeat(2, 1fr); }
  .news-grid { grid-template-columns: repeat(2, 1fr); }

  .admin-header { position: relative; width: auto; inset: auto; flex-direction: row; align-items: center; padding: 1rem; }
  .admin-brand { margin: 0; }
  .admin-lang { margin: 0; margin-inline-start: auto; }
  .admin-menu { display: block; margin-inline-start: .5rem; border: 1px solid rgba(255, 255, 255, .3); border-radius: var(--radius-xs); color: #fff; background: transparent; }
  .admin-header nav { position: absolute; top: 100%; inset-inline: 0; display: none; padding: 1rem; background: var(--navy-900); }
  .admin-header nav.open { display: flex; }
  .admin-main { margin: 0; }
}

@media (max-width: 767.98px) {
  .container { width: calc(100% - 2rem); }
  .section { padding-block: 3.5rem; }
  .hero-background { object-position: 32% center; }
  .hero-section::after { background: rgba(5, 12, 22, .74); }
  .hero-grid { padding-block: 3.5rem; gap: 2.5rem; }
  .hero-panel { grid-template-columns: 1fr; }
  .hero-panel div { border-inline-end: 0; border-bottom: 1px solid rgba(255, 255, 255, .12); }
  .hero-panel div:last-child { border-bottom: 0; }
  .hero-actions .btn { flex: 1 1 auto; }
  .news-grid, .footer-grid, .form-grid, .stat-grid { grid-template-columns: 1fr; }
  .category-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .category-card > div { padding: .75rem; }
  .quote-line { grid-template-columns: 76px minmax(0, 1fr); }
  .quote-line-image, .quote-line-image img { width: 76px; height: 76px; }
  .quote-line-actions { grid-column: 1 / -1; justify-items: stretch; }
  .quote-qty-form .form-control { width: 100%; }
  .detail-inquiry { width: 100%; }
  .detail-inquiry .form-control { width: 6rem; }
  .filter-panel > * { flex: 1 1 100%; }
  .cta-grid, .section-heading, .message-card header { align-items: flex-start; flex-direction: column; }
  .section-heading > a { align-self: flex-start; }
  .spec-list { grid-template-columns: 1fr; }
  .admin-main { padding: 1.25rem; }
  .admin-page-heading { align-items: flex-start; flex-direction: column; }
  .admin-detail dl { grid-template-columns: 1fr; }
  .order-line { grid-template-columns: 1fr; gap: .35rem; }
}

@media (max-width: 640px) {
  .chart { height: 160px; }
  .machine-bars li { grid-template-columns: 1fr; gap: .25rem; }
  .alert-list li { flex-direction: column; }
  .price-row { grid-template-columns: 1fr; gap: .3rem; }
}

/* Pages that open straight into content rather than a dark hero band still have
   to clear the fixed header. */
main > :first-child:not(.hero-section):not(.page-hero) { padding-top: calc(var(--header-h) + 2rem); }

/* ---- Corrections found by rendering the pages ---- */

/* The eyebrow's default is the light-mode accent, which is a dark orange. On the
   near-black hero bands that is barely a colour at all; inside one it takes the
   light end of the ramp instead. Scoped to the band rather than set per view, so
   a new page cannot forget it. */
.hero-section .eyebrow, .page-hero .eyebrow { color: var(--accent-text); }

/* The error page runs its heading the full width of the container, where the
   display step meant for a hero becomes a wall. */
.empty-state h1 { margin-inline: auto; max-width: 20ch; font-size: var(--step-3); }
.empty-state h2 { font-size: var(--step-2); }

/* A square field between two pill buttons reads as a mistake. */
.detail-inquiry .form-control, .quote-qty-form .form-control { border-radius: var(--radius-pill); text-align: center; }

/* The control is the browser's own, tinted by accent-color in base.css. Only
   the focus ring is ours, so that it matches every other field on the form. */
.form-check-input:focus-visible { outline: 0; box-shadow: 0 0 0 4px var(--accent-wash); }

/* A file input renders its own button plus the file name, which does not fit a
   half-width cell -- Chrome truncates the name to "N...en". Given the row to
   itself it fits. Browsers without :has() keep the old cramped cell rather than
   breaking, which is the right way for this to fail. */
.form-grid > div:has(input[type="file"]) { grid-column: 1 / -1; }
input[type="file"].form-control { padding: .55rem .75rem; }

/* The admin page ground and the old table-header fill were the same token, so
   the header row read as page rather than as part of the card below it. A rule
   under the header does the separating instead of a block of colour. */
.admin-table th {
  background: transparent;
  border-bottom: 1px solid var(--border);
}

.admin-table-wrap { overflow: hidden auto; }
.admin-table-wrap:has(.admin-table) { overflow-x: auto; }

/* The first control in a filter row is the search box, and 150px of basis
   truncates its placeholder to "Username / Full name / I". */
.admin-filter > *:first-child, .filter-panel > .filter-search { flex: 2 1 250px; }

/* In dark mode the sidebar and the page ground are within a few points of each
   other and the boundary between them disappears. A hairline restores it without
   touching the light theme, where the dark-on-bone contrast already does it. */
.admin-header { border-inline-end: 1px solid rgba(255, 255, 255, .07); }

/* The delete control in a row is a POST form, and a form is a block, so it broke
   to its own line under the edit link in every admin table. */
.table-actions form { display: inline-block; margin: 0; }

/* ============================ People and money ==========================
   Screens added with attendance, moulds, and the ledger. Same tokens, same
   shapes; nothing here introduces a colour or a radius of its own. */

/* The sidebar passed twenty destinations and became something to search rather
   than read, so it is grouped. The label is a caption, not a target. */
.nav-group {
  display: block;
  margin: 1.1rem .85rem .3rem;
  color: rgba(255, 255, 255, .45);
  font-size: var(--step--2);
  font-weight: 600;
  letter-spacing: .14em;
  text-transform: uppercase;
}

[dir="rtl"] .nav-group { letter-spacing: normal; text-transform: none; }

/* Clocking on. The one control on an employee's own page, so it is the size of
   a decision rather than a row in a table. */
.clock-card {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1.5rem;
  margin-bottom: 1.5rem;
  padding: 1.5rem 1.75rem;
  border: 1px solid var(--border-hair);
  border-radius: var(--radius-lg);
  background: var(--surface-raised);
}

.clock-card.on { border-inline-start: 4px solid var(--success); }
.clock-card.off { border-inline-start: 4px solid var(--border-strong); }
.clock-card > div { display: grid; gap: .2rem; }
.clock-card strong { font-family: var(--font-display); font-size: var(--step-3); font-weight: 500; letter-spacing: -.03em; }
.clock-card strong small { color: var(--text-muted); font-family: var(--font-body); font-size: var(--step--1); font-weight: 400; letter-spacing: 0; }
.clock-card p { margin: 0; color: var(--text-muted); font-size: var(--step--1); }
.clock-card form { margin: 0; }

.kicker {
  color: var(--text-muted);
  font-size: var(--step--2);
  font-weight: 600;
  letter-spacing: .12em;
  text-transform: uppercase;
}

[dir="rtl"] .kicker { letter-spacing: normal; text-transform: none; font-size: var(--step--1); }

/* Moulds are photographed objects, so they are shown as cards rather than rows:
   a picture of the cavity settles an argument a table of numbers cannot. */
.mould-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); gap: 1.1rem; }

.mould-card {
  display: flex;
  flex-direction: column;
  overflow: hidden;
  border: 1px solid var(--border-hair);
  border-radius: var(--radius-lg);
  background: var(--surface-raised);
  color: var(--text);
  text-decoration: none;
  transition: transform var(--dur-3) var(--ease-out-expo), box-shadow var(--dur-3) var(--ease-soft);
}

.mould-card:hover { transform: translateY(-4px); box-shadow: var(--shadow); color: var(--text); }

.mould-photo {
  display: grid;
  place-items: center;
  overflow: hidden;
  aspect-ratio: 4 / 3;
  margin: .5rem .5rem 0;
  border-radius: var(--radius);
  background: var(--surface-plate);
}

.mould-photo img { width: 100%; height: 100%; object-fit: cover; }

/* A mould with no photograph yet gets its code, so the card is still identifiable. */
.mould-photo-empty {
  color: var(--text-muted);
  font-family: var(--font-display);
  font-size: var(--step-4);
  font-weight: 500;
  letter-spacing: -.04em;
  text-transform: uppercase;
}

.mould-body { display: flex; flex: 1; flex-direction: column; gap: .5rem; padding: 1rem 1.1rem 1.15rem; }
.mould-body h3 { margin: 0; font-size: var(--step-1); }
.mould-status { display: flex; flex-wrap: wrap; gap: .35rem; margin-top: auto; }

.status-pill.mould-good { color: var(--success); background: var(--success-surface); }
.status-pill.mould-needsservice { color: var(--warning); background: var(--warning-surface); }
.status-pill.mould-inrepair { color: var(--danger); background: var(--danger-surface); }
.status-pill.mould-retired { color: var(--text-muted); background: var(--surface-sunken); }

.status-pill.invoice-draft { color: var(--text-muted); background: var(--surface-sunken); }
.status-pill.invoice-issued { color: var(--info); background: var(--info-surface); }
.status-pill.invoice-partlypaid { color: var(--warning); background: var(--warning-surface); }
.status-pill.invoice-paid { color: var(--success); background: var(--success-surface); }
.status-pill.invoice-void { color: var(--danger); background: var(--danger-surface); }

.status-pill.payroll-draft { color: var(--text-muted); background: var(--surface-sunken); }
.status-pill.payroll-approved { color: var(--info); background: var(--info-surface); }
.status-pill.payroll-paid { color: var(--success); background: var(--success-surface); }

/* A journal entry is one balanced thing, so it is drawn as one block rather than
   as rows in a table where the two halves could be read apart. */
.journal-list { display: grid; gap: 1rem; }

.journal-entry {
  padding: 1.1rem 1.2rem;
  border: 1px solid var(--border-hair);
  border-inline-start: 3px solid var(--accent);
  border-radius: var(--radius-sm);
  background: var(--surface);
}

.journal-entry.is-reversed { border-inline-start-color: var(--border-strong); opacity: .72; }
.journal-entry header { display: flex; align-items: flex-start; justify-content: space-between; gap: 1rem; margin-bottom: .5rem; }
.journal-entry header small { display: block; color: var(--text-muted); font-size: var(--step--2); }
.journal-entry .journal-actions { display: flex; align-items: center; gap: .6rem; }
.journal-entry table { margin: 0; }
.journal-entry .admin-table td { padding: .4rem .6rem; border-color: transparent; }
.journal-entry .admin-table small { display: block; color: var(--text-muted); font-size: var(--step--2); }

.report-columns { display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: 2rem; }
.report-columns h3 { margin: 0 0 .8rem; font-size: var(--step-1); }
.price-row.total { padding-top: .5rem; border-top: 1px solid var(--border); font-weight: 700; }

/* The picker that attaches an orphaned enrolment number to a person. */
.link-device { display: flex; gap: .4rem; margin: 0; }
.link-device .form-select { min-width: 11rem; }

@media (max-width: 767.98px) {
  .clock-card { align-items: stretch; flex-direction: column; }
  .clock-card form, .clock-card .btn { width: 100%; }
  .link-device { flex-direction: column; }
}

/* ---- Reveal a password -------------------------------------------------
   The wrapper is added by script around each password box, so none of this
   applies until the button it styles actually exists. */
.password-field { position: relative; display: block; }

/* Room for the button, on whichever side the writing mode puts it. */
.password-field .form-control { padding-inline-end: 3rem; }

.password-reveal {
  position: absolute;
  inset-inline-end: .35rem;
  inset-block-start: 50%;
  display: grid;
  place-items: center;
  width: 2.4rem;
  height: 2.4rem;
  padding: 0;
  transform: translateY(-50%);
  border: 0;
  border-radius: var(--radius-pill);
  color: var(--text-muted);
  background: transparent;
  cursor: pointer;
  transition: color var(--dur-1) var(--ease-soft), background-color var(--dur-1) var(--ease-soft);
}

.password-reveal:hover { color: var(--text); background: var(--surface-sunken); }
.password-reveal:focus-visible { outline: 0; color: var(--accent-text); box-shadow: 0 0 0 3px var(--accent-wash); }
.password-reveal svg { width: 1.15rem; height: 1.15rem; }

/* One icon at a time, and it shows what pressing will do rather than what is
   already true: an open eye offers to reveal, a crossed one offers to hide.
   That is the convention the app's login uses and the one Material and every
   other sign-in form uses, and the two had been drawing it opposite ways. */
.password-reveal .icon-eye { display: block; }
.password-reveal .icon-eye-off { display: none; }
.password-reveal[aria-pressed="true"] .icon-eye { display: none; }
.password-reveal[aria-pressed="true"] .icon-eye-off { display: block; }

/* ============================ Account =================================== */
/* Details and saved products side by side on a wide screen, stacked below it.
   The details panel is the narrower of the two: it is a short list, while the
   saved products need room for a grid of thumbnails. */
.account-grid { display: grid; gap: 1.5rem; grid-template-columns: minmax(0, 1fr); }
@media (min-width: 62rem) { .account-grid { grid-template-columns: minmax(0, 22rem) minmax(0, 1fr); } }

.account-panel {
  padding: 1.5rem;
  border: 1px solid var(--border-hair);
  border-radius: var(--radius);
  background: var(--surface);
}
.account-panel h2 { margin: 0 0 1rem; font-size: var(--step-1); }

.account-details { display: grid; grid-template-columns: auto 1fr; gap: .45rem 1rem; margin: 0 0 1.5rem; }
.account-details dt { color: var(--text-muted); font-size: .9rem; }
.account-details dd { margin: 0; overflow-wrap: anywhere; }

.favorite-cards { display: grid; grid-template-columns: repeat(auto-fill, minmax(160px, 1fr)); gap: 1rem; }
.favorite-card {
  display: grid;
  gap: .4rem;
  padding: .85rem;
  border: 1px solid var(--border-hair);
  border-radius: var(--radius-sm);
}
.favorite-card a { display: grid; gap: .5rem; color: inherit; text-decoration: none; }
.favorite-card img { width: 100%; height: auto; border-radius: var(--radius-sm); background: #fff; }
.favorite-card strong { font-size: .95rem; line-height: 1.3; }
.favorite-remove { justify-self: start; padding: 0; font-size: .85rem; }

.workspace-entry{display:inline-flex;align-items:center;gap:6px;min-height:44px;padding:8px 12px;border:1px solid rgba(255,255,255,.35);border-radius:10px;color:inherit;text-decoration:none;font-size:.85rem;white-space:nowrap;margin-inline-start:auto;margin-inline-end:10px}.workspace-entry svg{width:18px;height:18px;fill:none;stroke:currentColor;stroke-width:1.8}@media(min-width:992px){.workspace-entry{order:3;margin-inline-start:12px;margin-inline-end:0}}
