/* ===========================================================================
   hamudi.de — relaunch stylesheet
   ---------------------------------------------------------------------------
   Self-contained. Loaded ONLY by pages that set $relaunch_shell = true before
   including header.php, which means none of the Joomla/TZ-Portfolio bundle is
   present: no Bootstrap grid, no template reset, and — importantly — none of
   the `html{font-size:10px}` trick the fossil template relies on. rem here is
   a normal 16px root, so rem/clamp() can be used freely. Do not copy px-unit
   habits over from index.php's old inline <style> blocks.

   Design language: a white page, black type, one acid accent, and an
   ultra-condensed cap for anything that carries weight. Photographs are the
   only colour on the page — every surface around them is neutral on purpose.
   ======================================================================== */

:root {
    --rl-bg: #ffffff;
    --rl-fg: #0a0a0a;
    --rl-gray: #8e9095;
    --rl-hair: #e4e4e6;
    --rl-ink: #000000;
    --rl-accent: #ea2b74; /* his existing brand pink, used as the acid */
    --rl-ease: cubic-bezier(0.22, 1, 0.36, 1);
    --rl-pad: clamp(1.25rem, 4vw, 3.5rem);
}

/* --- reset ------------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
body.rl {
    margin: 0;
    background: var(--rl-bg);
    color: var(--rl-fg);
    font-family: 'Archivo', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
    font-size: 1.0625rem;
    font-stretch: 100%;
    line-height: 1.6;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    overflow-x: hidden;
}
/* The reset is wrapped in :where() so it contributes ZERO specificity and
   lands at (0,0,1) — element level.
   Written plainly as `.rl p { margin: 0 }` it scores (0,1,1) and silently
   beats every single-class rule that tries to give a paragraph a margin
   (.rl-ctfield, .rl-prose-tags, .rl-credit …), collapsing the spacing with no
   error anywhere. That bug was found twice before this reset was fixed; do not
   unwrap these. */
:where(.rl) img { max-width: 100%; display: block; }
:where(.rl) a { color: inherit; text-decoration: none; }
:where(.rl) h1, :where(.rl) h2, :where(.rl) h3,
:where(.rl) p, :where(.rl) ul, :where(.rl) figure { margin: 0; }
:where(.rl) ul { list-style: none; padding: 0; }
.rl ::selection { background: var(--rl-accent); color: #fff; }
.rl :focus-visible { outline: 2px solid var(--rl-accent); outline-offset: 4px; }

/* --- type roles --------------------------------------------------------
   .rl-display  the condensed cap. Anton only; never set a weight on it.
   .rl-label    the small uppercase UI label — Archivo pulled to 62% width,
                which is what makes navigation read as a caption, not a link.
   ---------------------------------------------------------------------- */
.rl-display {
    font-family: 'Anton', 'Archivo', Impact, sans-serif;
    font-weight: 400;
    text-transform: uppercase;
    line-height: 0.86;
    letter-spacing: -0.01em;
}
.rl-label {
    font-family: 'Archivo', sans-serif;
    font-stretch: 62%;
    font-weight: 600;
    font-size: 0.8125rem;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    line-height: 1.2;
}
.rl-lead {
    font-size: clamp(1.0625rem, 1.6vw, 1.3125rem);
    line-height: 1.65;
    color: #2c2c2e;
}

/* --- the page veil -----------------------------------------------------
   The reference fades its whole document in over 0.4s. Same idea: hold the
   first paint behind a white sheet so the hero photograph never appears
   half-decoded. Removed by JS on load; a `no-js` visitor never sees it
   because the element is only painted when the class is present.
   ---------------------------------------------------------------------- */
.rl-veil {
    position: fixed;
    inset: 0;
    background: var(--rl-bg);
    z-index: 300;
    pointer-events: none;
    opacity: 0;
    transition: opacity 0.6s ease;
}
.rl-veil.is-up { opacity: 1; pointer-events: auto; }

/* --- header ------------------------------------------------------------ */
.rl-head {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    z-index: 100;
    padding: clamp(0.9rem, 2vw, 1.35rem) var(--rl-pad);
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    /* difference-blend lets ONE header sit legibly over a dark photograph and
       over a white page with no light/dark variant to keep in sync — which is
       why the links carry no colour of their own. Its blind spot is mid-grey:
       white on #808080 differences back to #7f7f7f and vanishes. Below the
       first viewport, where photographs scroll under the bar, .is-stuck swaps
       in a frosted plate instead. */
    mix-blend-mode: difference;
    color: #fff;
    transition: background-color 0.4s ease, backdrop-filter 0.4s ease, color 0.4s ease;
}
.rl-head.is-stuck {
    mix-blend-mode: normal;
    color: var(--rl-fg);
    background: rgba(255, 255, 255, 0.78);
    backdrop-filter: blur(14px) saturate(140%);
    -webkit-backdrop-filter: blur(14px) saturate(140%);
    box-shadow: 0 1px 0 rgba(0, 0, 0, 0.06);
}
.rl-head a { transition: opacity 0.3s ease, color 0.3s ease; }
.rl-head a:hover { opacity: 0.5; }
/* The active item is marked with a RULE, not a colour, while the header is
   difference-blended: difference inverts against the backdrop, so the accent
   pink (#ea2b74) over a white page resolves to #15d48b and the current page
   reads as bright green. An underline in currentColor inverts with the text
   and stays correct on any background. Once the frosted plate is in (normal
   blend) the accent is safe again. */
.rl-head a.is-on {
    opacity: 1;
    border-bottom: 1px solid currentColor;
    padding-bottom: 2px;
}
.rl-head.is-stuck a.is-on { color: var(--rl-accent); border-bottom-color: var(--rl-accent); }
.rl-head-group { display: flex; gap: clamp(0.75rem, 2vw, 1.5rem); align-items: baseline; }

/* The centred wordmark. Absolutely placed so the two link groups stay pinned
   to the page edges regardless of how long the name renders. */
.rl-mark {
    position: absolute;
    left: 50%;
    transform: translateX(-50%);
    font-family: 'Anton', sans-serif;
    font-size: clamp(0.9rem, 1.5vw, 1.05rem);
    text-transform: uppercase;
    letter-spacing: 0.12em;
    white-space: nowrap;
    transition: letter-spacing 0.5s var(--rl-ease);
}
.rl-mark:hover { letter-spacing: 0.3em; opacity: 1 !important; }

@media (max-width: 640px) {
    .rl-mark { display: none; }
    .rl-head { font-size: 0.75rem; }
}

/* --- hero --------------------------------------------------------------- */
.rl-hero {
    position: relative;
    height: 100svh;
    min-height: 34rem;
    overflow: hidden;
    background: var(--rl-ink);
}
.rl-hero-media { position: absolute; inset: 0; }
.rl-hero-media img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    opacity: 0.82;
    transform: scale(1.04);
    animation: rl-drift 22s ease-out forwards;
}
@keyframes rl-drift { to { transform: scale(1.13); } }

/* A bottom scrim so the display type keeps contrast over any photograph. */
.rl-hero::after {
    content: '';
    position: absolute;
    inset: 0;
    background: linear-gradient(to top, rgba(0,0,0,0.72) 0%, rgba(0,0,0,0.15) 42%, rgba(0,0,0,0.35) 100%);
    pointer-events: none;
}
.rl-hero-inner {
    position: absolute;
    inset: 0;
    z-index: 2;
    display: flex;
    flex-direction: column;
    justify-content: flex-end;
    padding: var(--rl-pad);
    /* Clears the consent banner, which is fixed to the bottom on first visit. */
    padding-bottom: clamp(3.5rem, 9vh, 6rem);
    color: #fff;
}
.rl-hero-kicker { color: rgba(255,255,255,0.72); margin-bottom: auto; padding-top: clamp(4rem, 9vh, 6rem); }
.rl-hero h1 { display: block; }
.rl-hero-line {
    display: block;
    /* 12vw, not 15: two lines at 15vw plus the kicker and the keyword line
       overran a 900px-tall viewport and pushed the keywords under the consent
       banner. Check both lines still clear the banner before raising this. */
    font-size: clamp(2.75rem, 12vw, 10rem);
    color: #fff;
    /* Each line wipes up from its own baseline — the mask is on a wrapper so
       the clip never cuts descenders of the line above. */
    overflow: hidden;
}
.rl-hero-line > span {
    display: block;
    transform: translateY(105%);
    animation: rl-rise 1.1s var(--rl-ease) forwards;
}
.rl-hero-line:nth-child(2) > span { animation-delay: 0.1s; }
@keyframes rl-rise { to { transform: translateY(0); } }

/* The keyword line lives inside the <h1> so the heading still carries the
   terms the page ranks for, without printing them at display size. */
.rl-hero-sub {
    display: block;
    margin-top: clamp(0.75rem, 2vh, 1.25rem);
    font-family: 'Archivo', sans-serif;
    font-stretch: 62%;
    font-weight: 500;
    font-size: clamp(0.8125rem, 1.5vw, 1rem);
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: rgba(255,255,255,0.85);
    line-height: 1.5;
}
.rl-scroll-cue {
    position: absolute;
    right: var(--rl-pad);
    bottom: clamp(2rem, 6vh, 4.5rem);
    color: rgba(255,255,255,0.6);
    display: flex;
    align-items: center;
    gap: 0.6rem;
}
.rl-scroll-cue i {
    display: block;
    width: 1px;
    height: 2.5rem;
    background: rgba(255,255,255,0.5);
    transform-origin: top;
    animation: rl-cue 2.4s ease-in-out infinite;
}
@keyframes rl-cue { 0%,100% { transform: scaleY(0.25); } 50% { transform: scaleY(1); } }
@media (max-width: 640px) { .rl-scroll-cue { display: none; } }

/* --- section chrome ----------------------------------------------------- */
.rl-sec { padding: clamp(4rem, 11vh, 9rem) var(--rl-pad); }
.rl-sec-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 1rem;
    padding-bottom: 1.1rem;
    margin-bottom: clamp(2rem, 5vh, 3.5rem);
    border-bottom: 1px solid var(--rl-hair);
}
.rl-sec-head .rl-label { color: var(--rl-gray); }
.rl-sec-head em { font-style: normal; color: var(--rl-accent); }

/* --- the work index ----------------------------------------------------
   The signature interaction: a fixed full-bleed stage behind a list of
   categories. Hovering an entry cross-fades the stage to that gallery's
   cover and dims every sibling. The dimming is done with a parent :hover
   rather than JS so it still works if the script never loads.
   ---------------------------------------------------------------------- */
.rl-work {
    position: relative;
    background: var(--rl-ink);
    color: #fff;
    min-height: 100svh;
    display: flex;
    flex-direction: column;
    justify-content: center;
    padding: clamp(4rem, 10vh, 7rem) var(--rl-pad);
    overflow: hidden;
}
/* The stage holds the WHOLE frame, not a 100%-cover crop.
   Filling the section meant every cover was cropped to the viewport's aspect
   ratio, which on a wide window sliced heads off and cut the composition the
   photograph was made for. So on desktop the stage is inset to the right half
   — clear of the list — and the image is `contain`: the full frame, scaled to
   fit, never cropped. On narrow screens there is no room beside the list, so
   it falls back to a full-bleed cover behind the type. */
.rl-work-stage {
    position: absolute;
    top: clamp(3.5rem, 11vh, 7rem);
    right: clamp(1rem, 3vw, 3rem);
    bottom: clamp(2rem, 7vh, 4.5rem);
    left: 40%;
    z-index: 0;
}
.rl-work-stage img {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: contain;
    object-position: center right;
    opacity: 0;
    transform: scale(1.03);
    transition: opacity 0.9s ease, transform 1.6s var(--rl-ease);
}
.rl-work-stage img.is-active { opacity: 0.9; transform: scale(1); }

@media (max-width: 860px) {
    .rl-work-stage { inset: 0; }
    .rl-work-stage img { object-fit: cover; object-position: center; }
    .rl-work-stage img.is-active { opacity: 0.42; }
}
/* Vignette: keeps the list legible over any frame and gives the section the
   cinematic top/bottom fade the layout is built around. */
.rl-work::before {
    content: '';
    position: absolute;
    inset: 0;
    z-index: 1;
    pointer-events: none;
    /* Top and bottom fade only. The heavy left ramp that used to protect the
       list is unnecessary now the stage is inset to the right and no longer
       runs under the type — it only muddied the photograph. It comes back
       below 860px, where the frame IS behind the list again. */
    background:
        linear-gradient(to bottom, rgba(0,0,0,0.8) 0%, rgba(0,0,0,0) 20%, rgba(0,0,0,0) 78%, rgba(0,0,0,0.85) 100%);
}
@media (max-width: 860px) {
    .rl-work::before {
        background:
            linear-gradient(to bottom, rgba(0,0,0,0.85) 0%, rgba(0,0,0,0) 22%, rgba(0,0,0,0) 74%, rgba(0,0,0,0.9) 100%),
            linear-gradient(to right, rgba(0,0,0,0.88) 0%, rgba(0,0,0,0.55) 45%, rgba(0,0,0,0.2) 100%);
    }
}
.rl-work-inner { position: relative; z-index: 2; width: 100%; }
/* The stage now occupies the right of the section, so a head that stretches
   edge-to-edge drops its right-hand item on top of the photograph. Keep both
   head items together on the left, over the black. */
@media (min-width: 861px) {
    .rl-work .rl-sec-head { justify-content: flex-start; gap: clamp(1rem, 3vw, 2.5rem); }
}
/* "Hover to preview" is an instruction a touch device cannot follow. */
@media (hover: none), (pointer: coarse) { .rl-work-hint { display: none; } }
.rl-work-list { margin-top: clamp(1.5rem, 4vh, 2.5rem); }
.rl-work-item { border-top: 1px solid rgba(255,255,255,0.16); }
.rl-work-item:last-child { border-bottom: 1px solid rgba(255,255,255,0.16); }
.rl-work-item a {
    display: flex;
    align-items: baseline;
    gap: clamp(0.75rem, 2vw, 1.5rem);
    padding: clamp(0.5rem, 1.4vh, 0.9rem) 0;
    opacity: 0.88;
    transition: opacity 0.45s ease, color 0.45s ease, transform 0.55s var(--rl-ease);
}
.rl-work-list:hover .rl-work-item a { opacity: 0.3; }
.rl-work-list .rl-work-item a:hover,
.rl-work-list .rl-work-item a:focus-visible {
    opacity: 1;
    color: var(--rl-accent);
    transform: translateX(clamp(0.5rem, 2vw, 1.75rem));
}
/* Six entries plus the section head have to fit one viewport without the last
   one clipping — 7.5vw overran a 1440x900 window. Raising this means dropping
   an entry or letting the section grow past 100svh. */
.rl-work-name { font-size: clamp(1.5rem, 5vw, 4rem); }
.rl-work-count {
    font-family: 'Archivo', sans-serif;
    font-stretch: 62%;
    font-weight: 500;
    font-size: clamp(0.75rem, 1.2vw, 0.9375rem);
    letter-spacing: 0.1em;
    color: rgba(255,255,255,0.72);
    white-space: nowrap;
}
.rl-work-item a:hover .rl-work-count { color: var(--rl-accent); }
.rl-work-arrow { margin-left: auto; font-size: clamp(1rem, 2vw, 1.5rem); opacity: 0; transition: opacity 0.4s ease; }
.rl-work-item a:hover .rl-work-arrow { opacity: 1; }

/* --- marquee ------------------------------------------------------------ */
.rl-marquee {
    background: var(--rl-accent);
    color: #fff;
    padding: clamp(0.6rem, 1.6vh, 1rem) 0;
    overflow: hidden;
    white-space: nowrap;
}
.rl-marquee-track {
    display: inline-flex;
    gap: 2.5rem;
    padding-right: 2.5rem;
    animation: rl-marq 34s linear infinite;
    will-change: transform;
}
.rl-marquee span { font-family: 'Anton', sans-serif; text-transform: uppercase; font-size: clamp(1.1rem, 2.6vw, 2rem); letter-spacing: 0.02em; }
@keyframes rl-marq { to { transform: translateX(-50%); } }

/* --- selected frames ---------------------------------------------------
   A deliberately uneven editorial grid: 12 columns, items of different spans
   and vertical offsets, so it reads as a laid-out spread and not a gallery
   dump. Offsets collapse to zero below the tablet breakpoint.
   ---------------------------------------------------------------------- */
.rl-frames { display: grid; grid-template-columns: repeat(12, 1fr); gap: clamp(0.75rem, 2vw, 1.75rem); }
.rl-frame figure { position: relative; overflow: hidden; background: #f2f2f3; }
.rl-frame img { width: 100%; height: 100%; object-fit: cover; transition: transform 1.1s var(--rl-ease); }
.rl-frame:hover img { transform: scale(1.045); }
.rl-frame figcaption {
    display: flex;
    justify-content: space-between;
    gap: 1rem;
    margin-top: 0.7rem;
    color: var(--rl-gray);
}
.rl-frame-no { color: var(--rl-accent); }

.rl-frame--a { grid-column: 1 / span 7; }
/* Offsets stay small on purpose: the tallest item sets its row's height, so a
   large margin-top on a 3/4 frame leaves the landscape frame beside it sitting
   on a band of dead white. These are nudges, not a staircase. */
.rl-frame--b { grid-column: 9 / span 4; margin-top: clamp(1rem, 3.5vw, 3rem); }
.rl-frame--c { grid-column: 1 / span 4; }
.rl-frame--d { grid-column: 6 / span 7; margin-top: clamp(-2.5rem, -2vw, -0.5rem); }
.rl-frame--e { grid-column: 3 / span 5; }
.rl-frame--f { grid-column: 9 / span 4; margin-top: clamp(0.5rem, 2.5vw, 2rem); }

.rl-frame--a img, .rl-frame--d img { aspect-ratio: 3 / 2; }
.rl-frame--b img, .rl-frame--c img, .rl-frame--f img { aspect-ratio: 3 / 4; }
.rl-frame--e img { aspect-ratio: 1 / 1; }

@media (max-width: 860px) {
    .rl-frames { grid-template-columns: repeat(6, 1fr); }
    .rl-frame--a, .rl-frame--d, .rl-frame--e { grid-column: 1 / span 6; }
    .rl-frame--b, .rl-frame--c, .rl-frame--f { grid-column: span 3; }
    .rl-frame--b, .rl-frame--d, .rl-frame--f { margin-top: 0; }
}

/* --- statement / about -------------------------------------------------- */
/* Multi-line display text needs air that a one-word headline does not: at the
   0.86 the display role sets, the comma of one line lands on the caps of the
   next. Only the hero, which is one word per line, keeps the tighter value. */
.rl-statement { max-width: 22ch; font-size: clamp(2rem, 5.5vw, 4.5rem); line-height: 0.95; }
.rl-about-grid {
    display: grid;
    grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr);
    gap: clamp(1.5rem, 5vw, 5rem);
    align-items: start;
}
.rl-about-body > * + * { margin-top: 1.15rem; }
.rl-tags { display: flex; flex-wrap: wrap; gap: 0.45rem; margin-top: 1.75rem; }
.rl-tags li {
    border: 1px solid var(--rl-hair);
    border-radius: 999px;
    padding: 0.35rem 0.85rem;
    font-family: 'Archivo', sans-serif;
    font-stretch: 62%;
    font-weight: 600;
    font-size: 0.75rem;
    letter-spacing: 0.09em;
    text-transform: uppercase;
    color: #3a3a3c;
}
@media (max-width: 860px) { .rl-about-grid { grid-template-columns: 1fr; } }

/* --- link with an underline that draws on hover ------------------------- */
.rl-link {
    display: inline-block;
    font-family: 'Archivo', sans-serif;
    font-stretch: 62%;
    font-weight: 600;
    font-size: 0.9375rem;
    letter-spacing: 0.09em;
    text-transform: uppercase;
    padding-bottom: 0.2rem;
    background-image: linear-gradient(var(--rl-accent), var(--rl-accent));
    background-size: 0% 1px;
    background-position: 0 100%;
    background-repeat: no-repeat;
    transition: background-size 0.5s var(--rl-ease), color 0.35s ease;
}
.rl-link:hover { color: var(--rl-accent); background-size: 100% 1px; }

/* --- stories ------------------------------------------------------------ */
.rl-stories { display: grid; grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr)); gap: clamp(1.25rem, 3vw, 2.5rem); }
.rl-story { display: block; border-top: 1px solid var(--rl-fg); padding-top: 1rem; transition: color 0.35s ease; }
.rl-story:hover { color: var(--rl-accent); }
.rl-story h3 { font-family: 'Archivo', sans-serif; font-stretch: 80%; font-weight: 700; font-size: 1.25rem; line-height: 1.25; margin-top: 0.4rem; }
.rl-story p { color: var(--rl-gray); font-size: 0.9375rem; margin-top: 0.5rem; }

/* --- services ----------------------------------------------------------- */
.rl-svc { border-top: 1px solid var(--rl-hair); }
.rl-svc-row {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.4fr) auto;
    gap: clamp(1rem, 3vw, 3rem);
    align-items: baseline;
    padding: clamp(1.25rem, 3.5vh, 2.25rem) 0;
    border-bottom: 1px solid var(--rl-hair);
}
.rl-svc-name { font-size: clamp(1.5rem, 3.2vw, 2.5rem); }
.rl-svc-desc { color: #4a4a4d; font-size: 0.9375rem; line-height: 1.6; }
.rl-svc-price {
    font-family: 'Archivo', sans-serif;
    font-stretch: 62%;
    font-weight: 700;
    font-size: clamp(1rem, 2vw, 1.375rem);
    color: var(--rl-accent);
    white-space: nowrap;
}
@media (max-width: 860px) {
    .rl-svc-row { grid-template-columns: 1fr auto; }
    .rl-svc-desc { grid-column: 1 / -1; }
}

/* --- contact ------------------------------------------------------------ */
.rl-contact { background: var(--rl-ink); color: #fff; }
.rl-contact .rl-sec-head { border-color: rgba(255,255,255,0.2); }
.rl-contact-cta {
    display: inline-block;
    font-size: clamp(2.5rem, 11vw, 9rem);
    color: #fff;
    transition: color 0.4s ease;
}
.rl-contact-cta:hover { color: var(--rl-accent); }
.rl-contact-meta {
    display: flex;
    flex-wrap: wrap;
    gap: clamp(1rem, 4vw, 3.5rem);
    margin-top: clamp(1.75rem, 5vh, 3rem);
    color: rgba(255,255,255,0.6);
}
.rl-contact-meta strong { display: block; color: #fff; font-weight: 500; font-stretch: 100%; text-transform: none; letter-spacing: 0; font-size: 1rem; margin-top: 0.3rem; }
.rl-contact .rl-link { color: #fff; }
.rl-contact .rl-link:hover { color: var(--rl-accent); }

/* --- footer ------------------------------------------------------------- */
.rl-foot {
    background: var(--rl-ink);
    color: rgba(255,255,255,0.55);
    padding: clamp(2rem, 6vh, 3.5rem) var(--rl-pad);
    border-top: 1px solid rgba(255,255,255,0.14);
    display: flex;
    flex-wrap: wrap;
    gap: 1rem clamp(1rem, 3vw, 2.5rem);
    align-items: center;
    justify-content: space-between;
}
.rl-foot a { transition: color 0.3s ease; }
.rl-foot a:hover { color: var(--rl-accent); }
.rl-foot-nav { display: flex; flex-wrap: wrap; gap: clamp(0.75rem, 2vw, 1.75rem); }

/* --- scroll reveal ------------------------------------------------------ */
.rl-r { opacity: 0; transform: translateY(2rem); }
.rl-r.is-in {
    opacity: 1;
    transform: none;
    transition: opacity 1s var(--rl-ease), transform 1s var(--rl-ease);
}
/* Without JS nothing would ever get .is-in, so the whole page below the fold
   would stay invisible. Reveal is opt-in via a class on <html> set by the
   script itself — no script, no hiding. */
html:not(.rl-js) .rl-r { opacity: 1; transform: none; }

/* --- cursor ring -------------------------------------------------------- */
.rl-cursor {
    position: fixed;
    top: 0;
    left: 0;
    width: 2rem;
    height: 2rem;
    margin: -1rem 0 0 -1rem;
    border: 1px solid var(--rl-accent);
    border-radius: 50%;
    pointer-events: none;
    z-index: 250;
    opacity: 0;
    transition: opacity 0.3s ease, width 0.3s var(--rl-ease), height 0.3s var(--rl-ease),
        margin 0.3s var(--rl-ease), background-color 0.3s ease;
}
.rl-cursor.is-on { opacity: 1; }
.rl-cursor.is-big { width: 4rem; height: 4rem; margin: -2rem 0 0 -2rem; background: rgba(234, 43, 116, 0.14); }
@media (hover: none), (pointer: coarse) { .rl-cursor { display: none; } }

/* --- consent banner ----------------------------------------------------
   header.php styles the banner in Poppins, which the relaunch shell never
   loads. Re-point it at the fonts this page actually has.
   ---------------------------------------------------------------------- */
.rl #ga-consent, .rl #ga-consent button { font-family: 'Archivo', sans-serif; }

/* =========================================================================
   ABOUT PAGE
   ====================================================================== */

/* The one intro on the site that is not a full-bleed cover: a 4:5 portrait
   cropped to a 16:9 viewport would cut the face, so the photograph keeps its
   own frame and the type sits beside it. */
.rl-abhero {
    background: var(--rl-ink);
    color: #fff;
    display: grid;
    grid-template-columns: minmax(0, 1.1fr) minmax(0, 0.9fr);
    gap: clamp(1.5rem, 5vw, 5rem);
    align-items: center;
    padding: clamp(7rem, 16vh, 11rem) var(--rl-pad) clamp(3rem, 9vh, 6rem);
    min-height: 92svh;
}
.rl-abhero-kicker { color: var(--rl-accent); margin-bottom: clamp(1rem, 3vh, 2rem); }
.rl-abhero-word { display: block; font-size: clamp(2.75rem, 9vw, 7.5rem); color: #fff; }
.rl-abhero-sub {
    display: block; margin-top: clamp(0.75rem, 2vh, 1.25rem);
    font-family: 'Archivo', sans-serif; font-stretch: 62%; font-weight: 500;
    font-size: clamp(0.8125rem, 1.4vw, 1rem);
    letter-spacing: 0.16em; text-transform: uppercase; color: rgba(255,255,255,0.8);
}
.rl-abhero-photo { margin: 0; }
.rl-abhero-photo img { width: 100%; height: auto; display: block; }
.rl-abhero-photo figcaption { margin-top: 0.75rem; color: rgba(255,255,255,0.5); }
@media (max-width: 860px) {
    .rl-abhero { grid-template-columns: 1fr; min-height: 0; align-items: start; }
    .rl-abhero-photo { max-width: 22rem; }
}

/* --- the six bodies of work, as a list ---------------------------------- */
.rl-ablist { border-top: 1px solid var(--rl-hair); }
.rl-ablist-item { border-bottom: 1px solid var(--rl-hair); }
.rl-ablist-item a {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.3fr) auto;
    gap: clamp(1rem, 3vw, 3rem);
    align-items: baseline;
    padding: clamp(1rem, 3vh, 1.75rem) 0;
    transition: color 0.35s ease;
}
.rl-ablist-item a:hover { color: var(--rl-accent); }
.rl-ablist-name { font-size: clamp(1.375rem, 3vw, 2.25rem); }
.rl-ablist-blurb { color: #4a4a4d; font-size: 0.9375rem; line-height: 1.6; }
.rl-ablist-item a:hover .rl-ablist-blurb { color: var(--rl-accent); }
.rl-ablist-count { color: var(--rl-gray); white-space: nowrap; }
@media (max-width: 860px) {
    .rl-ablist-item a { grid-template-columns: 1fr auto; }
    .rl-ablist-blurb { grid-column: 1 / -1; }
}

.rl-credit { margin-top: clamp(2rem, 6vh, 3.5rem); color: rgba(255,255,255,0.45); }
.rl-credit a { color: rgba(255,255,255,0.75); border-bottom: 1px solid rgba(255,255,255,0.3); }
.rl-credit a:hover { color: var(--rl-accent); border-color: var(--rl-accent); }

/* =========================================================================
   GALLERY PAGES
   ====================================================================== */

/* --- intro: same full-bleed treatment as the homepage hero -------------- */
.rl-gintro {
    position: relative;
    height: 82svh;
    min-height: 26rem;
    overflow: hidden;
    background: var(--rl-ink);
}
.rl-gintro-media { position: absolute; inset: 0; }
.rl-gintro-media img {
    width: 100%; height: 100%; object-fit: cover;
    opacity: 0.8; transform: scale(1.04);
    animation: rl-drift 22s ease-out forwards;
}
.rl-gintro::after {
    content: '';
    position: absolute; inset: 0; pointer-events: none;
    background: linear-gradient(to top, rgba(0,0,0,0.78) 0%, rgba(0,0,0,0.12) 45%, rgba(0,0,0,0.38) 100%);
}
.rl-gintro-inner {
    position: absolute; inset: 0; z-index: 2;
    display: flex; flex-direction: column; justify-content: flex-end;
    padding: var(--rl-pad); padding-bottom: clamp(2.5rem, 7vh, 4.5rem);
    color: #fff;
}
/* Breadcrumb left, frame count right, both on one line at the top — stacking
   the count under the blurb crowded the three text blocks into one grey mass. */
.rl-gintro-top {
    display: flex; align-items: baseline; justify-content: space-between;
    gap: 1rem; margin-bottom: auto; padding-top: clamp(4rem, 9vh, 6rem);
}
.rl-gintro-kicker { color: rgba(255,255,255,0.7); }
.rl-gintro-kicker a { border-bottom: 1px solid rgba(255,255,255,0.35); }
.rl-gintro-kicker a:hover { border-color: var(--rl-accent); color: var(--rl-accent); }
.rl-gintro-title { color: #fff; }
.rl-gintro-word { display: block; font-size: clamp(2.75rem, 11vw, 9rem); }
.rl-gintro-sub {
    display: block; margin-top: 0.5rem;
    font-family: 'Archivo', sans-serif; font-stretch: 62%; font-weight: 500;
    font-size: clamp(0.75rem, 1.3vw, 0.9375rem);
    letter-spacing: 0.16em; text-transform: uppercase;
    color: rgba(255,255,255,0.75);
}
.rl-gintro-blurb {
    max-width: 42ch; margin-top: 0.9rem;
    font-size: clamp(0.9375rem, 1.5vw, 1.125rem);
    color: rgba(255,255,255,0.82); line-height: 1.55;
}
.rl-gintro-count { color: var(--rl-accent); white-space: nowrap; }

/* --- the frames --------------------------------------------------------
   CSS columns, not a row grid: mixed aspect ratios pack without cropping and
   without per-item span arithmetic. break-inside is what stops a figure being
   split across a column boundary — removing it silently tears photographs.
   ---------------------------------------------------------------------- */
.rl-gsec { padding-top: clamp(2.5rem, 7vh, 5rem); }
/* The copy block above the grid supplies its own bottom space; without this the
   two section paddings stack into a gap that reads as a missing element. */
.rl-gintro-text { padding-bottom: 0; }
.rl-gintro-measure { max-width: 44rem; }
.rl-gintro-measure .rl-lead { font-size: clamp(1.0625rem, 1.7vw, 1.3125rem); }
.rl-gintro-text + .rl-gsec { padding-top: clamp(1.5rem, 4vh, 2.5rem); }

/* --- the opening spread ----------------------------------------------------
   Copy left, one photograph right. The prose used to run down the left of a
   full-width section and leave the entire right half of the screen blank, which
   read as a page still loading rather than as a composition.

   Asymmetric on purpose: the text column is the narrower of the two and the
   photograph starts below the first line of type, so the two sides sit in a
   relationship instead of starting at the same height like a table. */
.rl-gintro-split {
    display: grid;
    grid-template-columns: minmax(0, 5fr) minmax(0, 6fr);
    gap: clamp(1.75rem, 5vw, 5rem);
    align-items: start;
}
.rl-gintro-split .rl-gintro-measure { max-width: 33rem; }
.rl-gintro-kick {
    color: var(--rl-accent);
    margin: 0 0 clamp(0.75rem, 1.6vw, 1.25rem);
}
.rl-gintro-cta { margin-top: clamp(1.25rem, 2.6vw, 2rem); }
/* The lead photograph. Dropped a little so the top of the frame lands against
   the second or third line of the paragraph rather than against its first. */
.rl-glead { margin: clamp(0.5rem, 3vw, 3.25rem) 0 0; }

@media (max-width: 900px) {
    .rl-gintro-split { grid-template-columns: 1fr; gap: clamp(1.5rem, 5vw, 2.5rem); }
    .rl-glead { margin-top: 0; }
    .rl-gintro-split .rl-gintro-measure { max-width: 44rem; }
}
.rl-gcols { columns: 3; column-gap: clamp(0.75rem, 1.6vw, 1.5rem); }
.rl-gfig { break-inside: avoid; margin: 0 0 clamp(0.75rem, 1.6vw, 1.5rem); }
.rl-gbtn {
    display: block; position: relative; width: 100%;
    padding: 0; border: 0; background: #f2f2f3; cursor: pointer;
    overflow: hidden; font: inherit; color: inherit;
}
.rl-gbtn img { width: 100%; height: auto; display: block; transition: transform 1.1s var(--rl-ease), opacity 0.4s ease; }
.rl-gbtn:hover img, .rl-gbtn:focus-visible img { transform: scale(1.035); opacity: 0.88; }
.rl-gno {
    position: absolute; left: 0.75rem; bottom: 0.6rem;
    color: #fff; text-shadow: 0 1px 8px rgba(0,0,0,0.75);
    opacity: 0; transition: opacity 0.35s ease;
}
.rl-gbtn:hover .rl-gno, .rl-gbtn:focus-visible .rl-gno { opacity: 1; }

/* --- like + share on the tile ---------------------------------------------
   Bottom-RIGHT, because the frame number already owns bottom-left. They sit in
   the figure rather than in the tile button: a <button> inside a <button> is
   invalid, and the tile's overflow:hidden would clip them anyway.

   Quiet by default and revealed with the rest of the tile's hover state, so a
   grid of 61 photographs still reads as photographs and not as a feed — but a
   frame that already has likes keeps its heart visible, because a count nobody
   can see is a count that never grows. */
/* The anchor is whatever element declares itself likeable — a gallery figure,
   or the media wrapper inside a homepage frame. One rule, both places. */
.rl-gfig, .rl-frame-media { position: relative; }
.rl-frame-media { display: block; }
.rl-gacts {
    position: absolute; right: 0.6rem; bottom: 0.6rem; z-index: 2;
    display: flex; align-items: center; gap: 0.2rem;
    opacity: 0; transition: opacity 0.35s ease;
}
[data-like-id]:hover .rl-gacts,
[data-like-id]:focus-within .rl-gacts { opacity: 1; }
.rl-gacts:has(.rl-glike.is-on) { opacity: 1; }
/* No hover on a touch screen — there the controls are simply always there. */
@media (hover: none) { .rl-gacts { opacity: 1; } }

.rl-gacts button {
    display: inline-flex; align-items: center; gap: 0.32rem;
    border: 0; cursor: pointer; color: #fff;
    background: rgba(0,0,0,0.5);
    font-family: 'Archivo', sans-serif; font-size: 0.62rem;
    letter-spacing: 0.09em; text-transform: uppercase; line-height: 1;
    padding: 0.45rem 0.6rem;
    transition: background 0.25s ease, color 0.25s ease;
}
.rl-gacts button:hover,
.rl-gacts button:focus-visible { background: rgba(0,0,0,0.78); color: var(--rl-accent); }
.rl-glike svg { display: block; transition: transform 0.2s ease; }
.rl-glike:active svg { transform: scale(0.85); }
.rl-glike.is-on { color: var(--rl-accent); }
.rl-glike.is-on svg path { fill: currentColor; }
.rl-glike.is-busy { opacity: 0.5; cursor: default; }
/* The count is absent, not zero, until a photograph actually has one. */
.rl-glike-n { font-variant-numeric: tabular-nums; }
.rl-glike-n:empty { display: none; }
.rl-gshare-label { white-space: nowrap; }

@media (max-width: 1100px) { .rl-gcols { columns: 2; } }
@media (max-width: 700px)  { .rl-gcols { columns: 1; } }

/* --- pager -------------------------------------------------------------- */
.rl-pager {
    display: grid; grid-template-columns: 1fr 1fr;
    gap: clamp(1rem, 3vw, 2.5rem);
    padding: clamp(2.5rem, 7vh, 5rem) var(--rl-pad);
    border-top: 1px solid var(--rl-hair);
}
.rl-pager-side { display: block; color: var(--rl-gray); transition: color 0.35s ease; }
.rl-pager-side:hover { color: var(--rl-accent); }
.rl-pager-next { text-align: right; }
.rl-pager-name { display: block; margin-top: 0.4rem; font-size: clamp(1.5rem, 4vw, 3rem); color: var(--rl-fg); transition: color 0.35s ease; }
.rl-pager-side:hover .rl-pager-name { color: var(--rl-accent); }

/* --- lightbox ----------------------------------------------------------
   Ours, because Fancybox ships in the fossil bundle this shell never loads.
   ---------------------------------------------------------------------- */
.rl-lb {
    position: fixed; inset: 0; z-index: 400;
    background: rgba(8,8,8,0.97);
    display: flex; align-items: center; justify-content: center;
    padding: clamp(2.5rem, 7vh, 4.5rem) clamp(1rem, 5vw, 5rem);
    opacity: 0; transition: opacity 0.35s ease;
}
.rl-lb.is-open { opacity: 1; }
.rl-lb[hidden] { display: none; }
.rl-lb-stage { margin: 0; max-width: 100%; max-height: 100%; display: flex; }
.rl-lb-img {
    max-width: 100%; max-height: 82svh;
    width: auto; height: auto; object-fit: contain;
    opacity: 0; transition: opacity 0.3s ease;
}
.rl-lb-img.is-ready { opacity: 1; }
.rl-lb button {
    position: absolute; background: none; border: 0; color: #fff;
    cursor: pointer; font-size: 1.75rem; line-height: 1;
    padding: 0.75rem 1rem; opacity: 0.65; transition: opacity 0.25s ease, color 0.25s ease;
    font-family: 'Archivo', sans-serif;
}
.rl-lb button:hover { opacity: 1; color: var(--rl-accent); }
.rl-lb-close { top: clamp(0.5rem, 2vh, 1.25rem); right: clamp(0.5rem, 2vw, 1.5rem); font-size: 2.25rem; }
.rl-lb-prev { left: clamp(0.25rem, 1.5vw, 1.5rem); top: 50%; transform: translateY(-50%); }
.rl-lb-next { right: clamp(0.25rem, 1.5vw, 1.5rem); top: 50%; transform: translateY(-50%); }
.rl-lb-meta {
    position: absolute; left: 0; right: 0; bottom: clamp(0.75rem, 2.5vh, 1.5rem);
    display: flex; justify-content: center; gap: 1rem;
    color: rgba(255,255,255,0.6); padding: 0 clamp(1rem, 5vw, 5rem); text-align: center;
}
.rl-lb-count { color: var(--rl-accent); }
.rl-lb-alt { max-width: 60ch; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* --- viewer actions: like + share ------------------------------------------
   Top-left, opposite the close button. The bottom edge is already spoken for:
   it carries the counter, and on a phone the prev/next controls move down there
   too, so anything placed there would sit on top of them.
   `.rl-lb button` is absolutely positioned as a rule; these two are laid out by
   their container instead, hence the position:static override. */
.rl-lb-acts {
    position: absolute;
    top: clamp(0.5rem, 2vh, 1.25rem);
    left: clamp(0.5rem, 2vw, 1.5rem);
    display: flex; align-items: center; gap: 0.25rem;
}
.rl-lb .rl-lb-acts button {
    position: static;
    display: inline-flex; align-items: center; gap: 0.45rem;
    font-size: 0.72rem; letter-spacing: 0.08em; text-transform: uppercase;
    padding: 0.6rem 0.75rem;
}
.rl-lb-like .rl-lb-heart { display: inline-flex; }
.rl-lb-like svg { display: block; transition: transform 0.2s ease; }
.rl-lb-like:active svg { transform: scale(0.85); }
.rl-lb-likes { font-variant-numeric: tabular-nums; }
/* Liked: the outline fills with the one accent colour the site allows itself. */
.rl-lb-like.is-on { opacity: 1; color: var(--rl-accent); }
.rl-lb-like.is-on svg path { fill: currentColor; }
/* In flight. The count is not touched until the server answers, so this is the
   only feedback between tap and truth. */
.rl-lb-like.is-busy { opacity: 0.35; cursor: default; }
.rl-lb-share-label { white-space: nowrap; }

/* The page must not scroll behind an open viewer. */
body.rl-lb-open { overflow: hidden; }
@media (max-width: 700px) {
    .rl-lb-prev, .rl-lb-next { top: auto; bottom: clamp(2.5rem, 8vh, 4rem); transform: none; }
    .rl-lb-alt { display: none; }
}

/* =========================================================================
   STORIES
   ====================================================================== */

.rl-storyhero {
    position: relative;
    background: var(--rl-ink);
    color: #fff;
    display: flex;
    align-items: flex-end;
    min-height: 72svh;
    overflow: hidden;
    padding: clamp(7rem, 16vh, 11rem) var(--rl-pad) clamp(2.5rem, 8vh, 5rem);
}
/* No photograph available — the plate carries the type on its own rather than
   leaving an empty picture frame. */
.rl-storyhero--bare { min-height: 60svh; align-items: center; }
.rl-storyhero-media { position: absolute; inset: 0; }
.rl-storyhero-media img { width: 100%; height: 100%; object-fit: cover; opacity: 0.72; }
.rl-storyhero:not(.rl-storyhero--bare)::after {
    content: '';
    position: absolute; inset: 0; pointer-events: none;
    background: linear-gradient(to top, rgba(0,0,0,0.82) 0%, rgba(0,0,0,0.15) 55%, rgba(0,0,0,0.4) 100%);
}
.rl-storyhero-inner { position: relative; z-index: 2; max-width: 46rem; }
.rl-storyhero-crumb { margin-bottom: 1.25rem; color: rgba(255,255,255,0.6); }
.rl-storyhero-crumb a:hover { color: var(--rl-accent); }
.rl-storyhero-meta { color: var(--rl-accent); margin-bottom: 0.85rem; }
.rl-storyhero-title { font-size: clamp(2rem, 6vw, 4.5rem); color: #fff; line-height: 0.95; }
.rl-storyhero-dek {
    margin-top: clamp(0.85rem, 2vh, 1.35rem);
    font-size: clamp(1rem, 1.8vw, 1.375rem);
    line-height: 1.5; color: rgba(255,255,255,0.82); max-width: 44ch;
}

/* --- the prose ---------------------------------------------------------
   One measure column. story_render_body() emits bare <p> and <blockquote>,
   so these are element selectors on purpose — there are no classes to hook.
   ---------------------------------------------------------------------- */
.rl-prose {
    max-width: 40rem;
    margin: 0 auto;
    padding: clamp(3rem, 9vh, 5.5rem) var(--rl-pad);
}
.rl-prose p {
    font-size: clamp(1.0625rem, 1.5vw, 1.1875rem);
    line-height: 1.75; color: #2e2e2e; margin: 0 0 1.35rem;
}
.rl-prose p:first-of-type { font-size: clamp(1.1875rem, 1.9vw, 1.4375rem); line-height: 1.6; color: var(--rl-fg); }
.rl-prose blockquote {
    margin: 2.25rem 0; padding: 0 0 0 1.4rem;
    border-left: 3px solid var(--rl-accent);
    font-size: clamp(1.1875rem, 2.2vw, 1.5rem); line-height: 1.45;
    font-style: italic; color: var(--rl-fg);
}
.rl-prose a { color: var(--rl-accent); border-bottom: 1px solid currentColor; }
.rl-prose-tags { margin-top: 2.5rem; }
.rl-prose-tags a { color: inherit; }
.rl-prose-tags li { padding: 0; }
.rl-prose-tags li a { display: block; padding: 0.35rem 0.85rem; border-bottom: 0; }
.rl-prose-tags li:hover { border-color: var(--rl-accent); color: var(--rl-accent); }
.rl-prose-source { margin-top: 1.75rem; color: var(--rl-gray); font-size: 0.9375rem; }
.rl-prose-source a { color: var(--rl-accent); }

/* --- the index ---------------------------------------------------------- */
.rl-sxlist { border-top: 1px solid var(--rl-hair); }
.rl-sxitem { border-bottom: 1px solid var(--rl-hair); }
.rl-sxitem a {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr) auto;
    gap: clamp(1rem, 3vw, 2.5rem);
    align-items: baseline;
    padding: clamp(1.25rem, 3.5vh, 2rem) 0;
    transition: color 0.35s ease;
}
.rl-sxitem a:hover { color: var(--rl-accent); }
.rl-sxno { color: var(--rl-accent); }
.rl-sxtitle { display: block; font-size: clamp(1.375rem, 3.4vw, 2.5rem); }
.rl-sxdek { display: block; margin-top: 0.45rem; color: #4a4a4d; font-size: 0.9375rem; line-height: 1.6; max-width: 52ch; }
.rl-sxitem a:hover .rl-sxdek { color: var(--rl-accent); }
.rl-sxmeta { color: var(--rl-gray); text-align: right; white-space: nowrap; line-height: 1.6; }
@media (max-width: 700px) {
    .rl-sxitem a { grid-template-columns: auto minmax(0, 1fr); }
    .rl-sxmeta { grid-column: 2; text-align: left; white-space: normal; }
}

/* --- newsletter --------------------------------------------------------- */
.rl-news { max-width: 40rem; }
.rl-contact-lead, .rl-news-lead { color: rgba(255,255,255,0.78); max-width: 44ch; }
.rl-news-form { display: flex; flex-wrap: wrap; gap: 0.6rem; margin-top: 1.75rem; }
.rl-news-form input[type="email"] {
    flex: 1 1 16rem;
    background: transparent;
    border: 1px solid rgba(255,255,255,0.35);
    color: #fff;
    font-family: 'Archivo', sans-serif; font-size: 1rem;
    padding: 0.85rem 1.1rem;
    transition: border-color 0.3s ease;
}
.rl-news-form input[type="email"]::placeholder { color: rgba(255,255,255,0.4); }
.rl-news-form input[type="email"]:focus { outline: none; border-color: var(--rl-accent); }
.rl-news-form button {
    flex: 0 0 auto;
    background: var(--rl-accent); color: #fff; border: 1px solid var(--rl-accent);
    font-family: 'Archivo', sans-serif; font-stretch: 62%; font-weight: 700;
    font-size: 0.875rem; letter-spacing: 0.12em; text-transform: uppercase;
    padding: 0.85rem 1.75rem; cursor: pointer;
    transition: background-color 0.3s ease, color 0.3s ease;
}
.rl-news-form button:hover { background: transparent; color: var(--rl-accent); }
.rl-news-ok { font-size: clamp(1.375rem, 3vw, 2.25rem); color: var(--rl-accent); margin-top: 1.5rem; }
.rl-news-err { margin-top: 0.85rem; color: #ff9ec4; font-size: 0.9375rem; }
.rl-news-fine { margin-top: 1rem; color: rgba(255,255,255,0.45); font-size: 0.8125rem; line-height: 1.6; }

/* The honeypot and screen-reader-only labels. .rl-hp must stay reachable to a
   bot filling every field but invisible and unreachable to a person — display:
   none would let a smarter bot skip it. */
.rl-hp { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }
.rl-sr {
    position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
    overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0;
}

/* =========================================================================
   CONTACT FORM
   The form sits on the dark plate, so every control is drawn as a hairline on
   black rather than a filled box — a default white input would punch six holes
   in the section.
   ====================================================================== */

.rl-ct-note { margin-top: 1.75rem; color: var(--rl-gray); font-size: 0.9375rem; }
.rl-ctgrid {
    display: grid;
    grid-template-columns: minmax(0, 1.5fr) minmax(0, 1fr);
    gap: clamp(1.75rem, 5vw, 4.5rem);
    align-items: start;
}
.rl-ctrow { display: grid; grid-template-columns: 1fr 1fr; gap: clamp(0.75rem, 2vw, 1.5rem); }
.rl-ctfield { display: block; margin-bottom: clamp(1rem, 2.5vh, 1.5rem); }
.rl-ctfield label { display: block; color: rgba(255,255,255,0.65); margin-bottom: 0.5rem; }
.rl-ct-opt { text-transform: none; letter-spacing: 0; color: rgba(255,255,255,0.4); }

.rl-ctform input[type="text"],
.rl-ctform input[type="email"],
.rl-ctform select,
.rl-ctform textarea {
    width: 100%;
    background: transparent;
    border: 0;
    border-bottom: 1px solid rgba(255,255,255,0.28);
    color: #fff;
    font-family: 'Archivo', sans-serif;
    font-size: 1rem;
    padding: 0.65rem 0;
    transition: border-color 0.3s ease;
    border-radius: 0;
}
.rl-ctform textarea { resize: vertical; line-height: 1.6; }
.rl-ctform ::placeholder { color: rgba(255,255,255,0.35); }
.rl-ctform input:focus, .rl-ctform select:focus, .rl-ctform textarea:focus {
    outline: none;
    border-bottom-color: var(--rl-accent);
}
/* A native <select> paints its own popup with the OS palette; only the closed
   control is ours. The dark option colour keeps the open list readable on the
   platforms that do inherit it. */
.rl-ctform select { appearance: none; -webkit-appearance: none; cursor: pointer; }
.rl-ctform select option { background: #141414; color: #fff; }

.rl-ctsend {
    margin-top: 0.75rem;
    background: var(--rl-accent);
    color: #fff;
    border: 1px solid var(--rl-accent);
    font-family: 'Archivo', sans-serif; font-stretch: 62%; font-weight: 700;
    font-size: 0.875rem; letter-spacing: 0.12em; text-transform: uppercase;
    padding: 0.95rem 2.25rem;
    cursor: pointer;
    transition: background-color 0.3s ease, color 0.3s ease;
}
.rl-ctsend:hover { background: transparent; color: var(--rl-accent); }

.rl-ct-err { display: block; margin-top: 0.4rem; color: #ff9ec4; font-size: 0.875rem; }
.rl-ct-err--form {
    border: 1px solid rgba(255,158,196,0.4);
    padding: 0.85rem 1.1rem;
    margin-bottom: 1.5rem;
}
.rl-ct-ok { font-size: clamp(1.75rem, 4.5vw, 3.25rem); color: var(--rl-accent); }

.rl-ctaside { border-left: 1px solid rgba(255,255,255,0.16); padding-left: clamp(1.25rem, 3vw, 2.5rem); }
.rl-ctaside h3 { color: rgba(255,255,255,0.65); margin-bottom: 0.85rem; }
.rl-ctaside-p { color: rgba(255,255,255,0.62); font-size: 0.9375rem; line-height: 1.65; margin-bottom: 1.25rem; }
.rl-ctaside-mail {
    display: inline-block;
    font-size: clamp(1rem, 2vw, 1.5rem);
    color: #fff;
    word-break: break-word;
    transition: color 0.3s ease;
}
.rl-ctaside-mail:hover { color: var(--rl-accent); }

@media (max-width: 860px) {
    .rl-ctgrid { grid-template-columns: 1fr; }
    .rl-ctrow { grid-template-columns: 1fr; }
    .rl-ctaside { border-left: 0; border-top: 1px solid rgba(255,255,255,0.16); padding-left: 0; padding-top: 1.75rem; }
}

/* =========================================================================
   LEGAL PAGE
   Element selectors: the carried-over German compliance markup has no classes
   to hook, and it must not be edited to acquire any.
   ====================================================================== */
.rl-legal h2 {
    font-family: 'Archivo', sans-serif; font-stretch: 80%; font-weight: 700;
    font-size: 1.125rem; letter-spacing: 0.01em;
    margin: 2.5rem 0 0.6rem; color: var(--rl-fg);
}
.rl-legal h2:first-child { margin-top: 0; }
.rl-legal p { font-size: 1rem; line-height: 1.75; }
.rl-legal p:first-of-type { font-size: 1rem; line-height: 1.75; color: #2e2e2e; }
.rl-legal address { font-style: normal; line-height: 1.8; font-size: 1rem; color: #2e2e2e; }
.rl-legal code { background: #f2f2f3; padding: 0.1rem 0.4rem; font-size: 0.875rem; }
.rl-legal a { color: var(--rl-accent); border-bottom: 1px solid currentColor; }
.rl-legal .muted { color: var(--rl-gray); font-size: 0.8125rem; margin-top: 2rem; }

/* --- motion preferences ------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
    html { scroll-behavior: auto; }
    .rl *, .rl *::before, .rl *::after {
        animation-duration: 0.001ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.001ms !important;
    }
    .rl-hero-line > span { transform: none; }
    .rl-hero-media img { animation: none; transform: none; }
    .rl-r { opacity: 1; transform: none; }
    .rl-cursor { display: none; }
}

/* =========================================================================
   BOOKING — the calendar, the times, and the shooting brief.
   Sits on the same dark plate as the contact form (.rl-contact) and reuses its
   controls (.rl-ctform, .rl-ctfield, .rl-ctrow, .rl-ctsend) rather than
   inventing a second set — two form languages on one site is how a design
   drifts. Everything below is only the parts a calendar needs.
   ====================================================================== */

.rl-bk { max-width: 62rem; }

/* Calendar and times side by side once there is room; stacked below that. The
   times column only exists after a day is picked, so the grid is declared with
   auto-flow rather than fixed tracks — an empty second column would leave the
   calendar visibly off-centre while nothing is selected. */
.rl-bk-stage {
    display: grid;
    gap: clamp(2rem, 5vw, 4rem);
    align-items: start;
}
@media (min-width: 900px) {
    .rl-bk-stage { grid-template-columns: minmax(0, 22rem) minmax(0, 1fr); }
}

.rl-bk-state {
    color: rgba(255,255,255,0.6);
    font-size: 0.9375rem;
    max-width: 34rem;
    line-height: 1.7;
}
.rl-bk-state + .rl-ctsend { margin-top: 1.5rem; }

/* --- month navigation --------------------------------------------------- */
.rl-bk-nav {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    padding-bottom: 1rem;
    border-bottom: 1px solid rgba(255,255,255,0.16);
}
.rl-bk-month { font-size: clamp(1.125rem, 2.4vw, 1.625rem); color: #fff; }
.rl-bk-arrow {
    background: transparent;
    border: 1px solid rgba(255,255,255,0.28);
    color: #fff;
    width: 2.5rem; height: 2.5rem;
    font-size: 1rem; line-height: 1;
    cursor: pointer;
    transition: border-color 0.3s ease, color 0.3s ease;
}
.rl-bk-arrow:hover:not(:disabled) { border-color: var(--rl-accent); color: var(--rl-accent); }
.rl-bk-arrow:disabled { opacity: 0.25; cursor: not-allowed; }

/* --- the day grid -------------------------------------------------------- */
.rl-bk-wd {
    display: grid;
    grid-template-columns: repeat(5, 1fr);
    gap: 0.375rem;
    margin: 1.25rem 0 0.5rem;
    color: rgba(255,255,255,0.45);
    text-align: center;
}
.rl-bk-grid { display: flex; flex-direction: column; gap: 0.375rem; }
.rl-bk-row { display: grid; grid-template-columns: repeat(5, 1fr); gap: 0.375rem; }

.rl-bk-day {
    display: flex; align-items: center; justify-content: center;
    /* 44px is the smallest reliable touch target; a calendar of 2.5rem buttons is
       the classic "I keep hitting the wrong day" control on a phone. */
    min-height: 2.75rem;
    background: transparent;
    border: 1px solid rgba(255,255,255,0.22);
    color: #fff;
    font-family: 'Archivo', sans-serif;
    font-size: 0.9375rem; font-weight: 600;
    cursor: pointer;
    transition: border-color 0.25s ease, background-color 0.25s ease, color 0.25s ease;
}
.rl-bk-day:hover { border-color: var(--rl-accent); color: var(--rl-accent); }
.rl-bk-day.is-on {
    background: var(--rl-accent);
    border-color: var(--rl-accent);
    color: #fff;
}
/* A day with nothing free, and the padding cells around the month. Not buttons:
   there is nothing to press, and a disabled button is still a tab stop on some
   browsers, which makes keyboard travel across a month needlessly long. */
.rl-bk-day.is-off, .rl-bk-day.is-blank {
    border-color: transparent;
    color: rgba(255,255,255,0.22);
    cursor: default;
}

/* --- the times ----------------------------------------------------------- */
.rl-bk-sub { color: rgba(255,255,255,0.45); margin-bottom: 0.5rem; }
.rl-bk-dayname {
    color: #fff;
    font-size: clamp(1rem, 2vw, 1.25rem);
    margin-bottom: 1.25rem;
}
.rl-bk-slots {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(6rem, 1fr));
    gap: 0.5rem;
}
.rl-bk-slot {
    min-height: 2.75rem;
    background: transparent;
    border: 1px solid rgba(255,255,255,0.22);
    color: #fff;
    font-family: 'Archivo', sans-serif;
    font-size: 0.9375rem; font-weight: 500;
    letter-spacing: 0.02em;
    cursor: pointer;
    transition: border-color 0.25s ease, background-color 0.25s ease, color 0.25s ease;
}
.rl-bk-slot:hover { background: var(--rl-accent); border-color: var(--rl-accent); color: #fff; }

/* --- the brief ----------------------------------------------------------- */
.rl-bk-form { max-width: 44rem; }
.rl-bk-back {
    background: transparent; border: 0; padding: 0;
    color: rgba(255,255,255,0.6);
    cursor: pointer;
    margin-bottom: 1.75rem;
    transition: color 0.25s ease;
}
.rl-bk-back:hover { color: var(--rl-accent); }

.rl-bk-chosen {
    border-left: 2px solid var(--rl-accent);
    padding-left: 1.125rem;
    margin-bottom: 2.5rem;
}
.rl-bk-chosen .rl-label { display: block; color: rgba(255,255,255,0.45); margin-bottom: 0.375rem; }
.rl-bk-chosen-when { display: block; font-size: clamp(1.125rem, 2.6vw, 1.75rem); color: #fff; }

.rl-bk-group {
    color: var(--rl-accent);
    margin: 2.5rem 0 1.25rem;
    padding-bottom: 0.625rem;
    border-bottom: 1px solid rgba(255,255,255,0.16);
}
.rl-bk-group:first-of-type { margin-top: 0; }

.rl-bk-consent { margin: 1.75rem 0 1.5rem; }
.rl-bk-consent label {
    display: flex; align-items: flex-start; gap: 0.75rem;
    color: rgba(255,255,255,0.62);
    font-size: 0.9375rem; line-height: 1.6;
    cursor: pointer;
}
.rl-bk-consent input { margin-top: 0.25rem; accent-color: var(--rl-accent); flex-shrink: 0; }

.rl-bk-err {
    margin-top: 1rem;
    color: #ff9ec4;
    font-size: 0.9375rem;
    border: 1px solid rgba(255,158,196,0.4);
    padding: 0.85rem 1.1rem;
}

/* --- confirmed ------------------------------------------------------------ */
.rl-bk-ok { max-width: 44rem; }
.rl-bk-ok:focus { outline: none; }
.rl-bk-ok-when {
    color: #fff;
    font-size: clamp(1.125rem, 2.6vw, 1.625rem);
    margin: 0.75rem 0 1.5rem;
}
.rl-bk-meet {
    display: inline-block;
    margin-top: 1.25rem;
    border-bottom: 1px solid currentColor;
    color: var(--rl-accent);
}

@media (max-width: 560px) {
    /* Two hairline controls per row is already tight at 560px; below it the labels
       wrap into each other and the pair reads as one confused field. */
    .rl-bk-form .rl-ctrow { grid-template-columns: 1fr; }
}

/* The booking hand-off on contact.php. A hairline band rather than a filled box:
   it has to read as a second door, not as an advertisement interrupting the page. */
.rl-bkcta {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    justify-content: space-between;
    gap: clamp(1.25rem, 4vw, 3rem);
    margin-top: clamp(2.5rem, 6vh, 4rem);
    padding-top: clamp(1.75rem, 4vh, 2.5rem);
    border-top: 1px solid var(--rl-hair);
}
.rl-bkcta-kicker { color: var(--rl-gray); margin-bottom: 0.625rem; }
.rl-bkcta-line { font-size: clamp(2rem, 6vw, 4rem); color: var(--rl-fg); }
.rl-bkcta-desc {
    margin-top: 0.875rem;
    max-width: 34rem;
    color: #3a3a3c;
    font-size: 0.9375rem;
    line-height: 1.7;
}
.rl-bkcta-go {
    flex-shrink: 0;
    background: var(--rl-accent);
    color: #fff;
    padding: 1rem 2rem;
    transition: background-color 0.3s ease, color 0.3s ease;
}
.rl-bkcta-go:hover { background: var(--rl-fg); color: #fff; }

/* The one-shot notice above the calendar (js/booking.js). Its only real use is
   "that time was just taken", which is why it reads as information rather than as
   an error: the visitor did nothing wrong, they were simply half a second late. */
.rl-bk-notice {
    grid-column: 1 / -1;
    border-left: 2px solid var(--rl-accent);
    padding: 0.75rem 0 0.75rem 1.125rem;
    margin-bottom: 0.5rem;
    color: #fff;
    font-size: 0.9375rem;
}
