/* ==========================================================================
   The Barber Castle — base layer: fonts, reset, type, layout primitives
   ========================================================================== */

@font-face {
  font-family: "Bebas Neue";
  src: url("../fonts/bebas-neue-400.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: "Inter";
  src: url("../fonts/inter-var.woff2") format("woff2");
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}

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

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  background: var(--bc-canvas);
}

@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }
}

body {
  margin: 0;
  background: var(--bc-canvas);
  color: var(--bc-ink);
  font-family: var(--font-body);
  font-size: var(--fs-body);
  line-height: var(--lh-body);
  font-weight: 400;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow-x: hidden;
}

img,
picture,
video,
canvas,
svg {
  display: block;
  max-width: 100%;
}

img {
  height: auto;
  background-color: var(--bc-surface);
}

/* --------------------------------------------------------------------------
   Anchor targets under a sticky masthead.

   The masthead is fixed, so a fragment link lands its target flush underneath it
   and the heading disappears behind the bar. The site has a lot of in-page
   targets — #menu, #craft, #film, #closing, the service ids on the menu rail —
   and only one selector in the whole stylesheet carried an offset, so most of
   them were hiding.

   Set globally on `:target` rather than per-section, because the correct offset
   is the header height and nothing else. It also has to cover the sticky chip
   index inside #menu, which adds its own row below the header, hence the extra
   60px.

   `:target` is what a fragment navigation actually matches, including the
   initial load of a URL that already carries a fragment, which is the case that
   was broken.
   -------------------------------------------------------------------------- */

:target {
  scroll-margin-top: calc(var(--header-h) + 60px);
}

/*
 * No flash or highlight on a targeted section. It was tried and removed: the
 * targets here are whole sections, and #menu is over 1,200px tall, so animating
 * a background across one repaints the entire block and reads as a glitch rather
 * than as an arrival. The offset alone is the fix.
 */

button,
input,
select,
textarea {
  font: inherit;
  color: inherit;
}

a {
  color: inherit;
  text-decoration: none;
}

:focus-visible {
  outline: 2px solid var(--bc-focus);
  outline-offset: 3px;
}

::selection {
  background: var(--bc-brass);
  color: #0d0f0e;
}

.visually-hidden {
  position: absolute !important;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

.skip-link {
  position: absolute;
  top: 0;
  left: 50%;
  transform: translate(-50%, -120%);
  z-index: 200;
  padding: 0.75rem 1.25rem;
  background: var(--bc-ink);
  color: var(--bc-canvas);
  font-size: var(--fs-meta);
  font-weight: 600;
  letter-spacing: var(--ls-label);
  text-transform: uppercase;
  transition: transform var(--dur) var(--ease-out);
}

.skip-link:focus-visible {
  transform: translate(-50%, 0);
}

/* --- Headings ---------------------------------------------------------- */

h1,
h2,
h3,
h4,
h5 {
  margin: 0;
  font-weight: 400;
  text-wrap: balance;
}

h1,
h2,
h3,
.display {
  font-family: var(--font-display);
  font-weight: 400;
  letter-spacing: var(--ls-display);
  line-height: var(--lh-display);
  text-transform: uppercase;
}

.t-display-xl {
  font-size: var(--fs-display-xl);
  line-height: var(--lh-tight);
}
.t-display-l {
  font-size: var(--fs-display-l);
}
.t-display-m {
  font-size: var(--fs-display-m);
}
.t-display-s {
  font-size: var(--fs-display-s);
  line-height: 1.08;
}

h4,
.t-h4 {
  font-family: var(--font-body);
  font-size: var(--fs-h4);
  font-weight: 600;
  letter-spacing: -0.005em;
  line-height: 1.3;
}

p {
  margin: 0 0 1.1em;
}

p:last-child {
  margin-bottom: 0;
}

/* --- Labels and meta ---------------------------------------------------- */

.eyebrow {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  margin: 0 0 1.25rem;
  font-size: var(--fs-meta);
  font-weight: 500;
  letter-spacing: var(--ls-meta);
  text-transform: uppercase;
  color: var(--bc-brass);
}

.eyebrow::before {
  content: "";
  width: 28px;
  height: 1px;
  background: var(--bc-brass);
  opacity: 0.7;
  flex: none;
}

.eyebrow--plain::before {
  display: none;
}

.lede {
  font-size: var(--fs-body-lg);
  color: var(--bc-ink-2);
  max-width: var(--measure);
  line-height: 1.55;
}

.meta {
  font-size: var(--fs-meta);
  color: var(--bc-ink-3);
  letter-spacing: 0.02em;
}

.mono-num {
  font-variant-numeric: tabular-nums;
}

/* --- Layout primitives --------------------------------------------------- */

.shell {
  width: 100%;
  max-width: var(--shell-max);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

.shell--narrow {
  max-width: var(--shell-narrow);
}

.section {
  position: relative;
  padding-block: var(--section-y);
}

.section--tight {
  padding-block: clamp(2.5rem, 5vw, 4.5rem);
}

.section--flush-top {
  padding-top: 0;
}

.rule {
  height: 1px;
  background: var(--bc-line);
  border: 0;
  margin: 0;
}

.section-head {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  justify-content: space-between;
  gap: var(--s-5);
  margin-bottom: clamp(2rem, 3.5vw, 3.25rem);
}

.section-head__text {
  max-width: 62ch;
}

.section-head__text .t-display-m {
  margin-bottom: 0.6rem;
}

.section-head__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-3);
}

.bg-canvas-2 {
  background: var(--bc-canvas-2);
}

.bg-green {
  background: var(--bc-green);
  color: var(--bc-ink);
}

.bg-green .lede,
.bg-green .meta {
  color: rgba(244, 242, 236, 0.78);
}

.bg-surface {
  background: var(--bc-surface);
}

/* --- Entrance motion (progressive enhancement) --------------------------- */

[data-reveal] {
  opacity: 0;
  transform: translate3d(0, 18px, 0);
  transition:
    opacity var(--dur-slow) var(--ease-out),
    transform var(--dur-slow) var(--ease-out);
  transition-delay: var(--reveal-delay, 0ms);
  will-change: opacity, transform;
}

[data-reveal].is-in {
  opacity: 1;
  transform: none;
}

@media (prefers-reduced-motion: reduce) {
  [data-reveal] {
    opacity: 1;
    transform: none;
    transition: none;
  }
}

.no-js [data-reveal] {
  opacity: 1;
  transform: none;
}

/* ==========================================================================
   Arabic / RTL

   The hard guarantees. tokens.css remaps --ls-* and the font stacks, which
   covers every rule that reads a token; these rules cover the ones that do not.

   `letter-spacing: 0 !important` on the universal selector is not laziness, it
   is the only way to hold the line. The sheets carry 41 letter-spacing
   declarations and a good number of them are literal em values — 0.08em on
   .menu__index, 0.34em on .boot__label, 0.1em on the star row — so a token-level
   fix provably misses them, and each one would break Arabic joins on its own.
   The same argument applies to text-transform: Latin text that has not been
   translated yet should not appear in capitals inside an Arabic paragraph.
   Nothing here can change a layout size, because Arabic has no case and zero
   tracking is always narrower than positive tracking.

   This also covers ::before/::after, which is where a good deal of the
   decorative uppercase text on this site actually lives.
   ========================================================================== */

[dir="rtl"] *,
[dir="rtl"] *::before,
[dir="rtl"] *::after {
  letter-spacing: 0 !important;
  text-transform: none !important;
  word-spacing: normal;
}

/* --- The display face -------------------------------------------------------

   Arabic has no condensed display cut. There is no system equivalent of Bebas
   Neue's narrow all-caps, and shipping one would mean adding an Arabic webfont,
   which is a decision about weight and licensing that this layer does not get
   to make silently. So the display role is kept — headings are still the
   display family at display sizes — and the scale is carried by weight instead
   of by width: 700 against the Latin face's 400. Arabic letterforms are already
   dense and high-contrast at 400, so 400 would make the hierarchy disappear
   rather than read as bold.

   h4/.t-h4 keep 600, which is already heavier than the Latin rule, and the small
   meta roles (eyebrow, nav, buttons) go up one step for the same reason: with
   tracking gone they lose the airy label look that separated them, and weight is
   what now does that separating. */

[dir="rtl"] h1,
[dir="rtl"] h2,
[dir="rtl"] h3,
[dir="rtl"] .display,
[dir="rtl"] .t-display-xl,
[dir="rtl"] .t-display-l,
[dir="rtl"] .t-display-m,
[dir="rtl"] .t-display-s {
  font-weight: 700;
  line-height: var(--lh-display);
}

[dir="rtl"] .t-display-xl {
  line-height: var(--lh-tight);
}

[dir="rtl"] h4,
[dir="rtl"] .t-h4 {
  font-weight: 700;
}

[dir="rtl"] .eyebrow {
  font-weight: 700;
}

[dir="rtl"] .btn,
[dir="rtl"] .nav a,
[dir="rtl"] .link-arrow,
[dir="rtl"] .meta,
[dir="rtl"] .mono-num {
  font-weight: 600;
}

/* --- Bidi isolation ------------------------------------------------------

   Arabic pages carry runs of text that are not Arabic and cannot be: phone
   numbers, "AED 350", a Dubai street address, an email address. The Unicode
   bidi algorithm lays those out in the paragraph direction, so inside an RTL
   page `+971 4 553 0061` reorders to `0061 553 4 971+` — the visitor reads a
   wrong phone number. Prices survive only because "AED" is a strong LTR
   character that anchors the run; a bare number would not.

   `unicode-bidi: plaintext` is the right tool rather than `isolate` because
   these slots are shared: the same `<dd>` holds an English address today and an
   Arabic one once it is translated. `plaintext` resolves the base direction per
   paragraph from the content itself, so a slot is correct either way, whereas
   forcing `direction: ltr` would point Arabic text the wrong way.

   THE text-align COMPANION IS NOT OPTIONAL. `text-align: start` is resolved
   against the paragraph direction, not the element's `direction` — so the moment
   plaintext settles an English address as LTR, `start` flips to mean LEFT and
   the address jumps to the wrong edge of an RTL column. The physical `right` is
   used to pin these blocks to the RTL inline start, which is where they belong
   in both cases: right-aligned Arabic and right-aligned Latin alike.

   Scoped to [dir="rtl"], so no English byte or pixel changes. */

/* Block-level slots: isolate the direction AND pin the alignment. */
[dir="rtl"] address,
[dir="rtl"] .footer__branch,
[dir="rtl"] dd,
[dir="rtl"] .pkg__price {
  unicode-bidi: plaintext;
  text-align: right;
}

/* Inline runs: direction only. text-align does not apply to these. */
[dir="rtl"] a[href^="tel:"],
[dir="rtl"] a[href^="mailto:"],
[dir="rtl"] .mono-num,
[dir="rtl"] .profile-row__url {
  unicode-bidi: plaintext;
}

/* The link inside such a slot needs the same treatment, and the reason is worth
   recording: `.hero__facts a` and friends are given `display: inline-flex` as a
   44px touch target. An inline-flex box is a block container, so its text
   becomes an anonymous flex item with its OWN bidi paragraph whose base
   direction comes from the inherited `direction` — not from the plaintext
   setting on the parent. Setting plaintext on the parent alone therefore leaves
   "25 Vincitore Boulevard, Arjan" reversed on touch viewports and correct on
   desktop, which is the worst kind of bug to ship. */
[dir="rtl"] dd a,
[dir="rtl"] address a {
  unicode-bidi: plaintext;
}

/* --- The content layer ----------------------------------------------------

   The rules above fix the slots whose values are facts. The same reordering
   also hits ordinary copy, and there the symptom is worse than cosmetic:
   "1 facial · 3 haircuts · 1 manicure · 1 pedicure" — a membership's terms —
   renders as "facial · 3 haircuts · 1 manicure · 1 1 pedicure", because the
   leading numeral is pulled to the end of an RTL paragraph and lands next to the
   final one. The page then states that a plan includes a treatment it does not.

   So the content layer gets the same treatment by element type rather than by
   class, which is what stops the next new content type from reintroducing it.

   It is a no-op for translated copy: plaintext resolves Arabic to RTL, which is
   what the page already was. It only changes the rendering of Latin runs, i.e.
   of the strings the translator has not reached yet.

   MAINTENANCE: any new text-bearing element type needs to be added here. The
   check that finds the misses is a painted-order comparison, not a visual one —
   see the note in the RTL section of this file's sibling, verify_ar.py. */
/* Blocks: direction AND alignment. `right` is the RTL inline start, and it is
   physical on purpose — `start` would re-resolve per paragraph and flip to
   left the moment a paragraph's content settles as Latin. */
[dir="rtl"] p,
[dir="rtl"] li,
[dir="rtl"] dd,
[dir="rtl"] dt,
[dir="rtl"] h1,
[dir="rtl"] h2,
[dir="rtl"] h3,
[dir="rtl"] h4,
[dir="rtl"] td,
[dir="rtl"] th,
[dir="rtl"] caption,
[dir="rtl"] figcaption,
[dir="rtl"] address,
[dir="rtl"] .pkg__price {
  unicode-bidi: plaintext;
  text-align: right;
}

/* Inline runs: direction only. text-align does not apply to these, so nothing
   here can disturb a centred button or a centred label. */
[dir="rtl"] span,
[dir="rtl"] b,
[dir="rtl"] s,
[dir="rtl"] a,
[dir="rtl"] .link-underline {
  unicode-bidi: plaintext;
}

/* Blocks that are centred by design, opting back out. The closing statement and
   the immersive gallery's empty state are both set centred in the base sheets,
   and a blanket `right` would visibly wreck them. */
[dir="rtl"] .closing p,
[dir="rtl"] .closing h2,
[dir="rtl"] .closing .eyebrow,
[dir="rtl"] .immersive__fallback p {
  text-align: center;
}

/* --- Centred absolute elements ----------------------------------------------

   The skip link, the closing watermark and every `left: 50%` + `translateX(-50%)`
   pair are centre calculations, not direction. They are left exactly as they
   are: flipping them would move the skip link off the middle of the viewport. */