@import "tailwindcss";
@plugin "daisyui";

/* Zento brand theme: white background, ink sidebar and text, one terracotta accent (dark text on it), the film's default accent too.
   Rounded, roomy shapes in the spirit of creative tools (Higgsfield, fal.ai). */
@plugin "daisyui/theme" {
  name: "zento";
  default: true;
  color-scheme: light;
  --color-base-100: #ffffff;
  --color-base-200: #f5f5f4;
  --color-base-300: #ebebe8;
  --color-base-content: #101009;
  --color-primary: #101009;
  --color-primary-content: #ffffff;
  --color-secondary: #45463f;
  --color-secondary-content: #ffffff;
  --color-accent: #c7856b;
  --color-accent-content: #101009;
  --color-neutral: #101009;
  --color-neutral-content: #ffffff;
  --color-info: #45463f;
  --color-info-content: #ffffff;
  --color-success: #3f6b3a;
  --color-success-content: #ffffff;
  --color-warning: #c7856b;
  --color-warning-content: #101009;
  --color-error: #c2330b;
  --color-error-content: #ffffff;
  --radius-selector: 2rem;
  --radius-field: 0.75rem;
  --radius-box: 1.25rem;
  --size-selector: 0.25rem;
  --size-field: 0.25rem;
  --border: 1px;
  --depth: 0;
  --noise: 0;
}

@font-face {
  font-family: "Hanken Grotesk";
  font-style: normal;
  font-weight: 400 800;
  font-display: swap;
  src: url("/assets/hanken-grotesk-latin-62d0893d.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: "Hanken Grotesk";
  font-style: normal;
  font-weight: 400 800;
  font-display: swap;
  src: url("/assets/hanken-grotesk-latin-ext-c2a3301f.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C4, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@theme {
  --font-sans: "Hanken Grotesk", ui-sans-serif, system-ui, sans-serif;
  --color-paper: #ffffff;
  --color-muted: #76776f;
  --color-hairline: #dededa;
  --color-accent-ink: #9a5a42;
  /* Credits: a yellow coin with a black bolt. */
}

@layer base {
  body {
    @apply bg-base-200 text-base-content antialiased;
  }
}

/* Zento components. Use these classes instead of raw DaisyUI btn/table/input
   modifiers so every screen shares one size and one look. */
@layer components {
  /* Buttons: one height (40px), one radius; variants change color only. */
  .button {
    @apply inline-flex h-10 cursor-pointer items-center justify-center gap-2 whitespace-nowrap rounded-field px-4 text-sm font-semibold transition-colors disabled:cursor-not-allowed disabled:opacity-50;
  }

  .button svg {
    @apply size-4 shrink-0;
  }

  .button-primary {
    @apply bg-neutral text-paper hover:bg-accent hover:text-neutral;
  }

  .button-accent {
    @apply bg-accent text-neutral hover:bg-[#d29a83];
  }

  .button-danger {
    @apply bg-error text-error-content hover:bg-error/85;
  }

  .button-secondary {
    @apply bg-base-300 text-base-content hover:bg-[#e2e2de];
  }

  .button-ghost {
    @apply text-secondary hover:bg-base-300 hover:text-base-content;
  }

  .button-sm {
    @apply h-8 px-3 text-xs;
  }

  .button-block {
    @apply w-full;
  }

  /* Filled field with the label inside (inputs, selects, textareas, files). */
  /* A field shows it can be edited: lighter under the pointer, light with the accent ring while typing. A disabled
     one stays as it is. */
  .field-filled {
    @apply flex cursor-text flex-col gap-0.5 rounded-field bg-base-300 px-3.5 py-2 transition-colors
      hover:bg-base-200 focus-within:bg-base-100 focus-within:ring-2 focus-within:ring-accent
      has-disabled:cursor-default has-disabled:hover:bg-base-300;
  }

  .field-filled > label {
    @apply text-xs font-medium text-muted;
  }

  .field-filled > input,
  .field-filled > select,
  .field-filled > textarea {
    @apply w-full bg-transparent text-sm outline-none placeholder:text-muted/70;
  }

  .field-filled > select {
    @apply -ml-0.5 cursor-pointer appearance-none;
  }

  .field-filled > textarea {
    @apply min-h-24 resize-y py-1;
  }

  /* A filled field on white with a hairline border, for a select that must not read as disabled (the template in
     the new-film form); its chevron says it opens. */
  .field-outlined {
    @apply bg-base-100 ring-1 ring-hairline hover:bg-base-100 hover:ring-base-content/25;
  }

  .field-outlined > select {
    @apply bg-no-repeat pr-6;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%237a7a72' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
    background-position: right center;
    background-size: 1rem;
  }

  /* A filled field drawn open, on white with a 1.5px hairline border, where a visitor meets the form first (the /apply
     hero): there the grey filled field reads as disabled. */
  /* The landing's fields: white with one hairline border that turns ink on focus (no second ring), compact. */
  .field-bordered {
    @apply gap-0 border border-hairline bg-base-100 py-1.5 hover:border-base-content/30 hover:bg-base-100
      focus-within:border-base-content focus-within:bg-base-100 focus-within:ring-0;
  }

  .field-bordered > label {
    @apply text-[11px];
  }

  .field-bordered > input {
    @apply text-[15px] placeholder:text-muted;
  }

  /* Chrome's autofill paints fields light blue; keep the landing's fields white. */
  .field-bordered > input:-webkit-autofill,
  [data-link-box] input:-webkit-autofill {
    -webkit-box-shadow: 0 0 0 1000px var(--color-base-100) inset;
    -webkit-text-fill-color: var(--color-base-content);
  }

  /* The start.zento.pl landing: a 1360px column, a 120px section rhythm (72px on a phone), big balanced headings with
     the emphasis in the accent ink, roomy leads. */
  .landing-wrap {
    @apply mx-auto w-full max-w-[1360px] px-4 sm:px-8;
  }

  .landing-section {
    @apply py-18 lg:py-30;
  }

  .landing-h2 {
    @apply text-[clamp(36px,4.4vw,56px)] font-extrabold leading-[1.02] tracking-[-0.03em] text-balance
      [&_em]:not-italic [&_em]:text-accent-ink;
  }

  .landing-lead {
    @apply mt-4.5 max-w-[620px] text-lg leading-[1.55] text-secondary text-pretty sm:text-[19px];
  }

  /* The landing's big call to action: 56px, one radius, the arrow nudges on hover. */
  .landing-button {
    @apply inline-flex h-14 shrink-0 cursor-pointer items-center justify-center gap-2.5 whitespace-nowrap rounded-[14px] px-7
      text-[17px] font-bold transition-colors focus-visible:outline-2 focus-visible:outline-offset-3 focus-visible:outline-accent;
  }

  .landing-button svg {
    @apply size-5 shrink-0 transition-transform duration-300 ease-out;
  }

  .landing-button:hover svg {
    @apply -translate-y-0.5;
  }

  /* The dark bands (the pain, the final call): light text, the emphasis in the accent itself. */
  .landing-dark {
    @apply bg-neutral text-base-200 [&_.landing-h2_em]:text-accent [&_.landing-lead]:text-[#c3c4bc];
  }

  /* The films' search above the list (search_box_tag). */
  .search-box {
    @apply flex h-10 w-full items-center gap-2 rounded-field bg-base-100 px-3 ring-1 ring-hairline transition-shadow
      focus-within:ring-2 focus-within:ring-accent sm:w-80;
  }

  .search-box > input {
    @apply w-full min-w-0 bg-transparent text-sm outline-none placeholder:text-muted/70;
  }

  /* A filter in a row of small buttons (admin/funnels): a date or a select shaped like them. */
  .filter-pill {
    @apply h-8 cursor-pointer rounded-field bg-base-300 px-3 text-xs font-semibold text-base-content outline-none transition-colors
      hover:bg-[#e2e2de] focus-visible:ring-2 focus-visible:ring-accent;
  }

  /* A film on the office's list (reels/card): the cover on top, the text under it; the title's link covers the card. */
  .reel-card {
    @apply relative flex flex-col overflow-hidden rounded-box border border-hairline bg-base-100 transition-shadow
      hover:shadow-[0_6px_20px_-12px_rgb(16_16_9/0.25)];
  }

  .reel-card-highlighted {
    @apply border-accent ring-2 ring-accent/40;
  }

  .reel-card-title {
    @apply line-clamp-2 text-sm font-semibold leading-snug after:absolute after:inset-0 focus-visible:outline-none
      focus-visible:after:rounded-box focus-visible:after:ring-2 focus-visible:after:ring-accent;
  }

  .reel-card-menu {
    @apply grid size-8 cursor-pointer place-items-center rounded-full bg-base-100/90 text-base-content shadow-sm
      hover:bg-base-100;
  }

  /* On a phone the page margin already frames it, so the panel keeps less padding of its own. */
  .panel {
    @apply rounded-box bg-base-100 p-4 sm:p-6;
  }

  /* Tables: one rounded bordered panel, muted headers, tall rows without dividers. */
  .table-panel {
    @apply overflow-x-auto rounded-box border border-hairline bg-base-100 px-3 py-2;
  }

  .data-table {
    @apply w-full text-left text-sm;
  }

  .data-table th {
    @apply px-3 py-3 font-medium text-muted;
  }

  .data-table td {
    @apply px-3 py-3.5 align-middle;
  }

  .data-table tbody tr {
    @apply transition-colors hover:bg-base-200/60;
  }

  .data-table tbody tr td:first-child {
    @apply rounded-l-field;
  }

  .data-table tbody tr td:last-child {
    @apply rounded-r-field;
  }

  /* Chips for roles and statuses. */
  .chip {
    @apply inline-flex items-center gap-1.5 rounded-full bg-base-300 px-2.5 py-0.5 text-xs font-medium text-secondary;
  }

  .chip-accent {
    @apply bg-accent/15 text-accent-ink;
  }

  .chip-error {
    @apply bg-error/15 text-error;
  }

  .chip-success {
    @apply bg-success/15 text-success;
  }

  .chip-muted {
    @apply bg-transparent text-muted ring-1 ring-hairline;
  }

  .amount-positive {
    @apply font-semibold text-success;
  }

  .amount-negative {
    @apply font-semibold text-accent-ink;
  }

  .nav-item {
    @apply flex h-10 items-center gap-3 rounded-field px-3 text-sm font-medium text-paper/70 transition-colors hover:bg-white/5 hover:text-paper;
  }

  .nav-item[aria-current="page"] {
    @apply bg-white/10 text-paper;
  }

  .nav-item[aria-current="page"] svg {
    @apply text-accent;
  }

  /* The reminder after the demo: the phone stands on a warm glow and is cut at the bottom, like a poster. */
  .onboarding-reminder-art {
    background: radial-gradient(60% 80% at 50% 110%, rgb(226 200 176 / 0.9), transparent 70%), #f3efe6;
  }

  /* The welcome modal's right half: a dark coupon with two notches on the seam and pills for the plans. */
  .coupon {
    @apply relative flex flex-col gap-3 bg-neutral px-8 py-9 text-paper sm:px-9;
  }

  .coupon::before,
  .coupon::after {
    content: "";
    @apply absolute -left-3.5 size-7 rounded-full bg-base-100 max-md:hidden;
  }

  .coupon::before {
    @apply -top-3.5;
  }

  .coupon::after {
    @apply -bottom-3.5;
  }

  .coupon [role="tab"] {
    @apply cursor-pointer rounded-full border border-paper/25 px-3 py-1 text-xs font-bold text-paper/80 transition-colors;
  }

  .coupon [role="tab"][aria-selected="true"] {
    @apply border-accent text-paper;
  }

  /* After the onboarding: a link typing itself into the message box. */
  .welcome-typing {
    display: inline-block;
    overflow: hidden;
    white-space: nowrap;
    border-right: 2px solid currentColor;
    max-width: 0;
    animation: welcome-typing 2.4s steps(44) 0.6s forwards, welcome-caret 0.8s step-end infinite;
  }

  @keyframes welcome-typing {
    to { max-width: 100%; }
  }

  @keyframes welcome-caret {
    50% { border-color: transparent; }
  }

  /* The onboarding: the menu shows what is coming, locked. */
  .nav-item-locked {
    @apply cursor-not-allowed text-paper/35 hover:bg-transparent hover:text-paper/35;
  }

  /* Listing photos: checked photos are numbered in grid order and the first one carries the cover badge. */
  .photo-grid {
    counter-reset: photo;
  }

  .photo-grid > li:has(:checked) {
    counter-increment: photo;
  }

  .photo-grid > li:has(:checked) .photo-number::before {
    content: counter(photo);
  }

  .photo-grid > li:not(:has(:checked)) .photo-cover,
  .photo-grid > li:has(:checked) ~ li .photo-cover {
    display: none;
  }

  .photo-grid > li:has(input:disabled:not(:checked)) label {
    @apply cursor-not-allowed;
  }

  /* The carousel's dashes, one per card: long and dark for the cards in view. */
  .carousel-dashes > button {
    @apply h-1.5 w-5 cursor-pointer rounded-full bg-base-300 transition-all duration-300 hover:bg-muted;
  }

  .carousel-dashes > button[data-seen] {
    @apply w-9 bg-neutral;
  }

  .photo-grid > li[data-dragging] {
    @apply opacity-30;
  }
}

/* Asystent. The composer is the one prominent object: a white card with a soft lift that deepens while typing, and a
   round send button, the only accent on the page at rest. Answers read as plain text on the page, never in bubbles. */
@layer components {
  .composer {
    @apply mx-auto flex max-w-3xl items-end gap-2 rounded-[1.75rem] bg-base-100 py-2 pr-2 pl-5 ring-1 ring-hairline transition-shadow
      shadow-[0_10px_30px_-12px_rgb(16_16_9/0.22),0_2px_6px_-2px_rgb(16_16_9/0.08)]
      focus-within:ring-[#c4c4bd] focus-within:shadow-[0_14px_36px_-12px_rgb(16_16_9/0.28),0_2px_6px_-2px_rgb(16_16_9/0.1)];
  }

  /* 16px keeps iOS from zooming in; about eight lines, then it scrolls. */
  .composer-input {
    @apply block max-h-52 min-h-10 w-full resize-none bg-transparent py-2 text-base leading-6 outline-none placeholder:text-muted;
  }

  .composer-button {
    @apply grid size-10 shrink-0 cursor-pointer place-items-center rounded-full transition-colors;
  }

  .composer-button-send {
    @apply bg-accent text-neutral hover:bg-[#d29a83];
  }

  .composer:has(.composer-input:placeholder-shown) .composer-button-send {
    @apply cursor-default bg-base-300 text-muted;
  }

  .composer-button-stop {
    @apply bg-neutral text-paper hover:bg-secondary;
  }

  /* The chips of a new chat: centred under the box on a wide screen, one row that scrolls sideways on a phone. */
  .suggestion-row {
    @apply mx-auto flex w-full max-w-3xl flex-wrap justify-center gap-2 px-3 sm:pt-1
      max-sm:order-1 max-sm:flex-nowrap max-sm:justify-start max-sm:overflow-x-auto max-sm:px-3 max-sm:pb-1 max-sm:[scrollbar-width:none];
  }

  .suggestion-chip {
    @apply inline-flex min-h-11 shrink-0 cursor-pointer whitespace-nowrap items-center gap-2 rounded-full bg-base-100 px-3.5 text-sm font-medium text-secondary ring-1 ring-hairline transition-colors hover:bg-base-200 hover:text-base-content;
  }

  .chat-prose {
    @apply text-[16px] leading-[1.7] break-words text-base-content;
  }

  .chat-prose > * + * {
    @apply mt-3.5;
  }

  .chat-prose :is(h1, h2, h3, h4) {
    @apply mt-6 text-lg leading-snug font-bold first:mt-0;
  }

  .chat-prose :is(ul, ol) {
    @apply flex flex-col gap-1.5 pl-6;
  }

  .chat-prose ul {
    @apply list-disc marker:text-accent;
  }

  .chat-prose ol {
    @apply list-decimal marker:text-muted;
  }

  .chat-prose strong {
    @apply font-semibold;
  }

  .chat-prose a {
    @apply font-medium text-accent-ink underline decoration-accent/50 underline-offset-2 hover:decoration-accent-ink;
  }

  .chat-prose code {
    @apply rounded-md bg-base-200 px-1.5 py-0.5 text-[0.9em];
  }

  .chat-prose pre {
    @apply overflow-x-auto rounded-xl bg-base-200 p-4 text-sm;
  }

  .chat-prose pre code {
    @apply bg-transparent p-0;
  }

  .chat-prose blockquote {
    @apply border-l-2 border-accent pl-4 text-secondary;
  }

  .chat-prose hr {
    @apply border-hairline;
  }

  .chat-prose table {
    @apply w-full text-left text-sm;
  }

  .chat-prose :is(th, td) {
    @apply border-b border-hairline px-2 py-1.5;
  }

  /* The soft cursor after the last streamed word. */
  .chat-prose-streaming > :last-child::after {
    content: "";
    @apply ml-1 inline-block size-2.5 translate-y-[-0.05em] rounded-full bg-accent align-middle motion-safe:animate-pulse;
  }

  /* Tool calls: a quiet status line per call, and the call's card (listing, film, list) under it. */
  .tool-status {
    @apply flex items-center gap-2 text-sm text-muted;
  }

  .tool-status-spinner {
    @apply size-3.5 shrink-0 rounded-full border-2 border-accent border-t-transparent motion-safe:animate-spin;
  }

  .tool-card {
    @apply max-w-xl rounded-2xl bg-base-100 ring-1 ring-hairline shadow-[0_6px_20px_-12px_rgb(16_16_9/0.18)];
  }

  /* A ready text to copy: title, the text as written, Kopiuj and the follow-up chips. */
  .result-card {
    @apply flex flex-col overflow-hidden rounded-2xl bg-base-100 ring-1 ring-hairline shadow-[0_6px_20px_-12px_rgb(16_16_9/0.18)];
  }

  .result-card-header {
    @apply flex items-center gap-3 border-b border-hairline bg-base-200/60 py-1.5 pr-1.5 pl-4;
  }

  .result-card-title {
    @apply min-w-0 flex-1 truncate text-sm font-semibold;
  }

  .result-card-body {
    @apply px-4 py-3.5 text-[15px] leading-[1.65] break-words whitespace-pre-wrap;
  }

  .result-card-footer {
    @apply flex flex-wrap items-center gap-2 border-t border-hairline px-3 py-2.5;
  }

  .result-card-copy {
    @apply inline-flex min-h-9 shrink-0 cursor-pointer items-center rounded-full bg-neutral px-3.5 text-sm font-medium text-paper transition-colors hover:bg-secondary;
  }

  .result-card-copy .result-card-copy-idle,
  [data-copied] .result-card-copy .result-card-copy-done {
    @apply inline-flex items-center gap-1.5;
  }

  .result-card-copy .result-card-copy-done,
  [data-copied] .result-card-copy .result-card-copy-idle {
    @apply hidden;
  }

  .result-card-chip {
    @apply inline-flex min-h-9 cursor-pointer items-center rounded-full px-3 text-sm font-medium text-secondary ring-1 ring-hairline transition-colors hover:bg-base-200 hover:text-base-content;
  }

  .typing-dots {
    @apply flex h-7 items-center gap-1.5;
  }

  /* A tool at work already says so with its own spinner. */
  .conversation:has(.tool-status[data-state="running"]) .typing-dots {
    @apply hidden;
  }

  .typing-dots span {
    @apply size-2 rounded-full bg-muted/60 motion-safe:animate-bounce;
  }

  .typing-dots span:nth-child(2) {
    animation-delay: 0.15s;
  }

  .typing-dots span:nth-child(3) {
    animation-delay: 0.3s;
  }
}

.honeypot {
  position: absolute;
  left: -10000px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

/* The film preview on Szablony: frames laid out in the film's own pixels (720 × 1280) through --u, one
   film pixel at the frame's width, so the preview keeps the film's proportions at any size. Colors and font come
   from the CSS variables set by film_preview_style. */
.film-frame {
  container-type: inline-size;
  position: relative;
  aspect-ratio: 9 / 16;
  overflow: hidden;
  border-radius: 1.1rem;
  box-shadow: 0 18px 40px -12px rgb(14 15 13 / 0.45), 0 0 0 1px rgb(14 15 13 / 0.08);
  line-height: 1.1;
}
.film-frame > * { position: absolute; --u: calc(100cqw / 720); }
/* The same frame in 16:9: the landscape sibling's pixels (1280 × 720), the parts moved where film/src/*_wide put them. */
.film-frame-wide { aspect-ratio: 16 / 9; }
.film-frame-wide > * { --u: calc(100cqw / 1280); }
.film-frame-wide .fm-shade { background: linear-gradient(color-mix(in srgb, var(--ink) 55%, transparent), transparent calc(var(--u) * 220), transparent 40%, color-mix(in srgb, var(--ink) 62%, transparent) 72%, color-mix(in srgb, var(--ink) 94%, transparent)); }
.film-frame-wide .fm-mark { left: calc(var(--u) * 56); top: calc(var(--u) * 48); }
.film-frame-wide .fm-stack { left: calc(var(--u) * 56); right: auto; width: calc(var(--u) * 640); gap: calc(var(--u) * 22); }
.film-frame-wide .fm-label { font-size: calc(var(--u) * 22); }
.film-frame-wide .fm-progress { left: calc(var(--u) * 56); right: calc(var(--u) * 56); bottom: calc(var(--u) * 36); }
.film-frame-wide .fk-photo { right: auto; width: calc(var(--u) * 780); height: 100%; }
.film-frame-wide .fk-plate { right: calc(var(--u) * 540); }
.film-frame-wide .fk-card { left: calc(var(--u) * 820); right: calc(var(--u) * 40); top: calc(var(--u) * 190); padding: calc(var(--u) * 30) calc(var(--u) * 34); border-radius: calc(var(--u) * 30); font-size: calc(var(--u) * 38); }
.film-frame-wide .fk-strip { left: calc(var(--u) * 820); gap: calc(var(--u) * 14); }
.film-frame-wide .fk-strip span { padding: calc(var(--u) * 15) calc(var(--u) * 8); border-radius: calc(var(--u) * 22); font-size: calc(var(--u) * 24); }
.film-frame-wide .fk-progress { left: calc(var(--u) * 820); }
.film-frame-wide .ff-window { top: 0; height: calc(var(--u) * 584); }
.film-frame-wide .ff-band { top: calc(var(--u) * 24); height: calc(var(--u) * 56); align-items: flex-start; z-index: 1; }
.film-frame-wide .ff-band-logo { width: calc(var(--u) * 200); height: calc(var(--u) * 56); padding: calc(var(--u) * 10) calc(var(--u) * 14); box-sizing: border-box; justify-content: center; border-radius: calc(var(--u) * 12); background: var(--ink); color: var(--on-ink); font-size: calc(var(--u) * 20); }
.film-frame-wide .ff-band-place { gap: calc(var(--u) * 2); padding: calc(var(--u) * 8) calc(var(--u) * 16); border-radius: calc(var(--u) * 12); background: var(--ink); }
.film-frame-wide .ff-street { font-size: calc(var(--u) * 22); color: var(--on-ink); }
.film-frame-wide .ff-district { font-size: calc(var(--u) * 14); color: var(--accent-on-dark); }
.film-frame-wide .ff-sticker { left: calc(var(--u) * 40); right: auto; top: calc(var(--u) * 584); justify-content: flex-start; }
.film-frame-wide .ff-sticker span { font-size: calc(var(--u) * 34); padding: calc(var(--u) * 14) calc(var(--u) * 26); }
.film-frame-wide .ff-room { left: calc(var(--u) * 40); right: auto; top: calc(var(--u) * 634); text-align: left; font-size: calc(var(--u) * 24); }
.film-frame-wide .ff-facts { left: auto; right: calc(var(--u) * 30); top: calc(var(--u) * 610); height: calc(var(--u) * 62); grid-template-columns: auto auto; font-size: calc(var(--u) * 26); }
.film-frame-wide .ff-facts span { padding: 0 calc(var(--u) * 34); }
.film-frame-wide .ff-progress { top: calc(var(--u) * 698); }
/* 16:9 covers and end cards (film/src/*_wide Intro and End). */
.film-frame-wide .fm-heading { font-size: calc(var(--u) * 112); }
.film-frame-wide .fm-end { left: 0; right: 0; width: auto; top: calc(var(--u) * 150); bottom: auto; align-items: center; text-align: center; gap: 0; }
.film-frame-wide .fm-price { font-size: calc(var(--u) * 104); margin: calc(var(--u) * 24) 0 calc(var(--u) * 16); }
.film-frame-wide .fm-facts { font-size: calc(var(--u) * 24); margin-bottom: calc(var(--u) * 36); }
.film-frame-wide .fm-invite { font-size: calc(var(--u) * 42); margin: calc(var(--u) * 30) 0 calc(var(--u) * 22); }
.film-frame-wide .fm-contact { font-size: calc(var(--u) * 26); }
.film-frame-wide .fk-col { left: calc(var(--u) * 820); right: calc(var(--u) * 40); }
.film-frame-wide .fk-price { top: calc(var(--u) * 40); font-size: calc(var(--u) * 62); }
.film-frame-wide .fk-price-end { font-size: calc(var(--u) * 64); }
.film-frame-wide .fk-where { top: calc(var(--u) * 116); font-size: calc(var(--u) * 24); white-space: normal; line-height: 1.2; }
.film-frame-wide .fk-tiles { top: calc(var(--u) * 200); gap: calc(var(--u) * 16); }
.film-frame-wide .fk-tiles span { padding: calc(var(--u) * 16) calc(var(--u) * 20); border-radius: calc(var(--u) * 22); font-size: calc(var(--u) * 27); }
.film-frame-wide .fk-tiles small { font-size: calc(var(--u) * 17); margin-bottom: calc(var(--u) * 4); }
.film-frame-wide .fk-card small { margin-top: calc(var(--u) * 10); font-size: calc(var(--u) * 26); }
.film-frame-wide .ff-intro-logo { left: calc(var(--u) * 425); top: calc(var(--u) * 190); }
.film-frame-wide .ff-intro-title { top: calc(var(--u) * 400); }
.film-frame-wide .ff-intro-label { top: calc(var(--u) * 470); font-size: calc(var(--u) * 22); }
.film-frame-wide .ff-end-place { top: calc(var(--u) * 70); font-size: calc(var(--u) * 32); }
.film-frame-wide .ff-chips { left: 0; right: 0; top: calc(var(--u) * 150); display: flex; justify-content: center; gap: calc(var(--u) * 22); }
.film-frame-wide .ff-chips .ff-chip { position: static; transform: none; font-size: calc(var(--u) * 40); padding: calc(var(--u) * 15) calc(var(--u) * 28); }
.film-frame-wide .ff-panel { height: calc(var(--u) * 330); }
.film-frame-wide .ff-price { top: calc(var(--u) * 30); }
.film-frame-wide .ff-per, .film-frame-wide .ff-contact { position: absolute; left: 0; right: 0; text-align: center; white-space: nowrap; }
.film-frame-wide .ff-per { top: calc(var(--u) * 135); font-size: calc(var(--u) * 34); }
.film-frame-wide .ff-contact { top: calc(var(--u) * 180); font-size: calc(var(--u) * 30); }
.film-frame-wide .ff-end-logo { bottom: calc(var(--u) * 24); height: calc(var(--u) * 60); font-size: calc(var(--u) * 22); }
/* Magazyn in the preview: the photo full frame under the style's dark, the lettering in what reads on it, labels and
   rules in the accent, headings in DM Serif Display (film/src/magazyn). */
.fm-photo { inset: 0; }
.fm-photo img { width: 100%; height: 100%; object-fit: cover; }
.fm-shade { inset: 0; background: linear-gradient(color-mix(in srgb, var(--ink) 55%, transparent), transparent calc(var(--u) * 260), transparent 42%, color-mix(in srgb, var(--ink) 62%, transparent) 70%, color-mix(in srgb, var(--ink) 94%, transparent)); }
.fm-shade-deep { background: color-mix(in srgb, var(--ink) 62%, transparent); }
.fm-mark { left: calc(var(--u) * 40); top: calc(var(--u) * 66); height: calc(var(--u) * 64); display: flex; align-items: center; color: var(--on-ink); font-size: calc(var(--u) * 26); letter-spacing: calc(var(--u) * 3); white-space: nowrap; }
.fm-mark-center { left: 0; right: 0; justify-content: center; }
.fm-plate { display: flex; align-items: center; height: 100%; padding: calc(var(--u) * 8) calc(var(--u) * 12); border-radius: calc(var(--u) * 12); background: var(--plate, var(--paper)); box-sizing: border-box; }
.fm-plate img { max-height: 100%; max-width: calc(var(--u) * 186); object-fit: contain; }
.fm-stack { left: calc(var(--u) * 40); right: calc(var(--u) * 40); display: flex; flex-direction: column; align-items: flex-start; gap: calc(var(--u) * 26); }
.fm-progress { left: calc(var(--u) * 40); right: calc(var(--u) * 40); bottom: calc(var(--u) * 40); height: calc(var(--u) * 4); border-radius: 999px; background: color-mix(in srgb, var(--on-ink) 25%, transparent); }
.fm-progress span { display: block; height: 100%; border-radius: 999px; background: var(--on-ink); }
.fm-label { color: var(--accent-on-dark); font-size: calc(var(--u) * 24); letter-spacing: calc(var(--u) * 6); text-transform: uppercase; white-space: nowrap; }
.fm-serif { font-family: 'DM Serif Display', serif; font-weight: 400; color: var(--on-ink); white-space: nowrap; line-height: 1.02; }
.fm-caption { font-size: calc(var(--u) * 64); }
.fm-heading { font-size: calc(var(--u) * 116); }
.fm-price { font-size: calc(var(--u) * 112); margin: calc(var(--u) * 26) 0 calc(var(--u) * 20); }
.fm-facts { color: var(--on-ink); opacity: 0.8; font-size: calc(var(--u) * 26); letter-spacing: calc(var(--u) * 4); text-transform: uppercase; white-space: nowrap; margin-bottom: calc(var(--u) * 44); }
.fm-rule { display: block; width: calc(var(--u) * 100); height: calc(var(--u) * 3); background: var(--accent-on-dark); }
.fm-invite { font-size: calc(var(--u) * 44); margin: calc(var(--u) * 34) 0 calc(var(--u) * 30); }
.fm-contact { color: var(--on-ink); opacity: 0.75; font-size: calc(var(--u) * 30); white-space: nowrap; }
/* Karta oferty in the preview (film/src/karta): the sheet in the light color mixed toward the dark, the photo across
   the top, light tiles and pills, the price in the accent that reads on the light color, cards in the accent. */
.fk-frame { background: var(--sheet, color-mix(in srgb, var(--paper) 94%, var(--ink))); color: var(--on-paper); }
.fk-photo { left: 0; right: 0; top: 0; height: calc(var(--u) * 773); overflow: hidden; }
.fk-photo img { width: 100%; height: 100%; object-fit: cover; }
.fk-pill { position: absolute; padding: calc(var(--u) * 13) calc(var(--u) * 27); border-radius: 999px; background: var(--paper); color: var(--on-paper); font-size: calc(var(--u) * 23); letter-spacing: 0.14em; text-transform: uppercase; white-space: nowrap; }
.fk-pill-dark { background: var(--ink); color: var(--on-ink); }
.fk-plate { right: calc(var(--u) * 40); top: calc(var(--u) * 40); height: calc(var(--u) * 60); max-width: calc(var(--u) * 300); padding: 0 calc(var(--u) * 20); border-radius: calc(var(--u) * 14); background: var(--plate, var(--paper)); color: var(--on-paper); display: flex; align-items: center; font-size: calc(var(--u) * 23); letter-spacing: 0.14em; white-space: nowrap; }
.fk-plate img { max-height: calc(var(--u) * 44); max-width: calc(var(--u) * 260); object-fit: contain; }
.fk-price { left: calc(var(--u) * 40); color: var(--accent-on-light); font-size: calc(var(--u) * 73); line-height: 1; white-space: nowrap; }
.fk-price-end { font-size: calc(var(--u) * 87); }
.fk-where { left: calc(var(--u) * 40); right: calc(var(--u) * 40); top: calc(var(--u) * 900); font-size: calc(var(--u) * 30); opacity: 0.7; white-space: nowrap; }
.fk-tiles { left: calc(var(--u) * 40); right: calc(var(--u) * 40); top: calc(var(--u) * 966); display: grid; grid-template-columns: 1fr 1fr; gap: calc(var(--u) * 20); }
.fk-tiles span, .fk-strip span { background: var(--paper); color: var(--on-paper); border-radius: calc(var(--u) * 27); padding: calc(var(--u) * 20) calc(var(--u) * 27); font-size: calc(var(--u) * 33); white-space: nowrap; }
.fk-tiles small { display: block; font-size: calc(var(--u) * 20); letter-spacing: 0.08em; text-transform: uppercase; opacity: 0.55; margin-bottom: calc(var(--u) * 6); }
.fk-card { left: calc(var(--u) * 40); right: calc(var(--u) * 40); padding: calc(var(--u) * 33) calc(var(--u) * 40); border-radius: calc(var(--u) * 33); background: var(--accent); color: var(--on-accent); font-size: calc(var(--u) * 40); line-height: 1.15; }
.fk-card small { display: block; margin-top: calc(var(--u) * 12); font-size: calc(var(--u) * 30); opacity: 0.9; }
.fk-strip { left: calc(var(--u) * 40); right: calc(var(--u) * 40); bottom: calc(var(--u) * 40); display: flex; gap: calc(var(--u) * 20); }
.fk-strip span { flex: 1; text-align: center; padding: calc(var(--u) * 17) calc(var(--u) * 10); font-size: calc(var(--u) * 28); }
.fk-progress { left: calc(var(--u) * 40); right: calc(var(--u) * 40); bottom: calc(var(--u) * 16); height: calc(var(--u) * 4); border-radius: 999px; background: color-mix(in srgb, var(--on-paper) 20%, transparent); }
.fk-progress span { display: block; height: 100%; border-radius: 999px; background: var(--on-paper); }
/* A film frame filling the phone's screen (the /apply hero) or a template chip's thumbnail. */
.film-frame.phone-film-frame { width: 100%; border-radius: 0; box-shadow: none; }
.film-frame.chip-frame { width: 100%; border-radius: 5px; box-shadow: none; }
.film-frame-mini { border-radius: 0.6rem; box-shadow: 0 8px 18px -8px rgb(14 15 13 / 0.4), 0 0 0 1px rgb(14 15 13 / 0.08); }
.ff-band { inset: 0 0 auto 0; height: calc(var(--u) * 170); display: flex; align-items: center; justify-content: space-between; padding: 0 calc(var(--u) * 30); }
.ff-band-logo { width: calc(var(--u) * 250); height: calc(var(--u) * 100); display: flex; align-items: center; color: var(--on-ink); font-size: calc(var(--u) * 34); text-transform: uppercase; white-space: nowrap; }
.ff-band-logo img, .ff-intro-logo img, .ff-end-logo img { max-width: 100%; max-height: 100%; object-fit: contain; }
.ff-band-place { display: flex; flex-direction: column; align-items: flex-end; gap: calc(var(--u) * 10); }
.ff-street { color: var(--on-ink); font-size: calc(var(--u) * 32); white-space: nowrap; }
.ff-district { color: var(--accent-on-dark); font-size: calc(var(--u) * 22); text-transform: uppercase; white-space: nowrap; }
.ff-window { left: 0; right: 0; top: calc(var(--u) * 170); height: calc(var(--u) * 830); }
.ff-window img { width: 100%; height: 100%; object-fit: cover; }
.ff-window::after { content: ""; position: absolute; inset: auto 0 0 0; height: 18%; background: linear-gradient(to bottom, transparent, var(--ink)); }
.ff-sticker { left: 0; right: 0; top: calc(var(--u) * 1000); display: flex; justify-content: center; transform: translateY(-50%); }
.ff-sticker span { background: var(--accent); color: var(--on-accent); font-size: calc(var(--u) * 54); padding: calc(var(--u) * 18) calc(var(--u) * 30); border-radius: calc(var(--u) * 16); transform: rotate(-2deg); text-transform: uppercase; white-space: nowrap; box-shadow: 0 calc(var(--u) * 16) calc(var(--u) * 34) rgb(14 15 13 / 0.32); }
.ff-room { left: 0; right: 0; top: calc(var(--u) * 1074); text-align: center; color: var(--accent-on-dark); font-size: calc(var(--u) * 28); letter-spacing: calc(var(--u) * 4); text-transform: uppercase; }
.ff-facts { left: calc(var(--u) * 30); right: calc(var(--u) * 30); top: calc(var(--u) * 1128); height: calc(var(--u) * 82); display: grid; grid-template-columns: 1fr 1fr; border: calc(var(--u) * 2) solid color-mix(in srgb, var(--on-ink) 25%, transparent); border-radius: calc(var(--u) * 16); color: var(--on-ink); font-size: calc(var(--u) * 30); }
.ff-facts span { display: flex; align-items: center; justify-content: center; }
.ff-facts span + span { border-left: calc(var(--u) * 2) solid color-mix(in srgb, var(--on-ink) 25%, transparent); }
.ff-progress { left: calc(var(--u) * 30); right: calc(var(--u) * 30); top: calc(var(--u) * 1242); height: calc(var(--u) * 6); background: color-mix(in srgb, var(--on-ink) 20%, transparent); border-radius: 999px; }
.ff-progress span { display: block; width: 55%; height: 100%; background: var(--accent); border-radius: inherit; }
.ff-intro-logo { left: calc(var(--u) * 145); top: calc(var(--u) * 427); width: calc(var(--u) * 430); height: calc(var(--u) * 170); display: flex; align-items: center; justify-content: center; color: var(--on-paper); font-size: calc(var(--u) * 54); text-transform: uppercase; white-space: nowrap; }
.ff-intro-title { left: 0; right: 0; top: calc(var(--u) * 666); text-align: center; color: var(--on-paper); font-size: calc(var(--u) * 40); text-transform: uppercase; }
.ff-intro-label { left: 0; right: 0; top: calc(var(--u) * 749); text-align: center; color: var(--accent-on-light); font-size: calc(var(--u) * 24); letter-spacing: calc(var(--u) * 2); text-transform: uppercase; }
.ff-end-place { left: 0; right: 0; top: calc(var(--u) * 300); text-align: center; color: var(--on-paper); font-size: calc(var(--u) * 34); text-transform: uppercase; }
.ff-chip { left: 50%; transform: translateX(-50%); background: var(--paper); color: var(--on-paper); box-shadow: inset 0 0 0 calc(var(--u) * 3) var(--on-paper); font-size: calc(var(--u) * 46); padding: calc(var(--u) * 10) calc(var(--u) * 30); border-radius: 999px; white-space: nowrap; }
.ff-panel { inset: auto 0 0 0; height: calc(var(--u) * 560); background: var(--accent); color: var(--on-accent); }
.ff-price { position: absolute; left: 0; right: 0; top: calc(var(--u) * 130); text-align: center; font-size: calc(var(--u) * 86); white-space: nowrap; }
.ff-end-logo { position: absolute; left: 0; right: 0; bottom: calc(var(--u) * 80); height: calc(var(--u) * 110); display: flex; align-items: center; justify-content: center; font-size: calc(var(--u) * 26); text-transform: uppercase; white-space: nowrap; }
/* The map and the extras in the preview (Map and Extras in film/src per template): a sample drawing (film_preview/map.svg) stands in for the map tiles,
   greyed as the film greys them; every colored part reads the same palette key as the film. */
.ff-map, .fm-map, .fk-map { overflow: hidden; }
.ff-map { inset: 0; filter: grayscale(0.78); }
.ff-map img, .fm-map img, .fk-map img { width: 100%; height: 100%; object-fit: cover; }
.ff-map::after { content: ""; position: absolute; inset: 0; background: rgba(241,236,224,0.18); }
.ff-map-dot { width: calc(var(--u) * 42); height: calc(var(--u) * 42); margin: calc(var(--u) * -21); border-radius: 50%; background: var(--on-paper); color: var(--paper); box-shadow: 0 0 0 calc(var(--u) * 4) var(--paper); font-size: calc(var(--u) * 22); display: flex; align-items: center; justify-content: center; }
.ff-map-dot-1 { left: 30%; top: 26%; } .ff-map-dot-2 { left: 70%; top: 32%; } .ff-map-dot-3 { left: 64%; top: 60%; }
.ff-map-pin { left: 50%; top: 40%; width: calc(var(--u) * 68); height: calc(var(--u) * 68); margin: calc(var(--u) * -104) 0 0 calc(var(--u) * -34); border-radius: 50%; background: var(--accent); }
.ff-map-pin::before { content: ""; position: absolute; left: 50%; top: 50%; width: calc(var(--u) * 26); height: calc(var(--u) * 26); margin: calc(var(--u) * -13); border-radius: 50%; background: var(--on-accent); }
.ff-map-pin::after { content: ""; position: absolute; left: 50%; top: 100%; width: calc(var(--u) * 34); height: calc(var(--u) * 34); margin: calc(var(--u) * -22) 0 0 calc(var(--u) * -17); background: var(--accent); transform: rotate(45deg); }
.ff-map-label { left: 50%; top: 40%; transform: translate(-50%, calc(var(--u) * -186)); background: var(--accent); color: var(--on-accent); font-size: calc(var(--u) * 36); padding: calc(var(--u) * 12) calc(var(--u) * 26); border-radius: 999px; white-space: nowrap; }
.ff-map-list { left: calc(var(--u) * 18); right: calc(var(--u) * 18); top: 60%; bottom: calc(var(--u) * -30); padding: calc(var(--u) * 26) calc(var(--u) * 28); border-radius: calc(var(--u) * 30); background: color-mix(in srgb, var(--paper) 96%, transparent); color: var(--on-paper); display: flex; flex-direction: column; gap: calc(var(--u) * 20); font-size: calc(var(--u) * 38); }
.ff-map-list li { display: flex; align-items: center; gap: calc(var(--u) * 20); white-space: nowrap; }
.ff-map-number { width: calc(var(--u) * 46); height: calc(var(--u) * 46); border-radius: 50%; background: var(--on-paper); color: var(--paper); font-size: calc(var(--u) * 24); display: flex; align-items: center; justify-content: center; flex-shrink: 0; }
.ff-map-name { flex: 1; overflow: hidden; text-overflow: ellipsis; }
.ff-map-min { color: var(--accent-on-light); }
.ff-extras-photo { inset: 0; }
.ff-extras-photo img { width: 100%; height: 100%; object-fit: cover; filter: brightness(0.62) saturate(0.6) blur(7px); transform: scale(1.1); }
.ff-extras-shade { inset: 0; background: linear-gradient(to bottom, transparent 40%, color-mix(in srgb, var(--ink) 70%, transparent)); }
.ff-extras-label { left: calc(var(--u) * 70); top: 26%; color: var(--accent-on-dark); font-size: calc(var(--u) * 58); letter-spacing: calc(var(--u) * 2); text-transform: uppercase; white-space: nowrap; }
.ff-extras { left: calc(var(--u) * 70); right: calc(var(--u) * 40); top: 36%; display: flex; flex-direction: column; gap: calc(var(--u) * 46); }
.ff-extras li { display: flex; align-items: center; gap: calc(var(--u) * 20); color: var(--on-ink); font-size: calc(var(--u) * 40); white-space: nowrap; text-shadow: 0 0 6px var(--ink), 0 0 6px var(--ink); }
.ff-check { width: calc(var(--u) * 46); height: calc(var(--u) * 46); border-radius: calc(var(--u) * 10); background: var(--accent); color: var(--on-accent); font-size: calc(var(--u) * 28); display: flex; align-items: center; justify-content: center; flex-shrink: 0; text-shadow: none; }
.fm-map { inset: 0; filter: grayscale(1) contrast(0.85); }
.fm-map-wash { inset: 0; background: color-mix(in srgb, var(--paper) 45%, transparent); }
.fm-map-pin { left: 50%; top: 36%; width: calc(var(--u) * 60); height: calc(var(--u) * 60); margin: calc(var(--u) * -30); border-radius: 50%; background: var(--accent); box-shadow: 0 8px 22px rgba(14,15,13,0.25); }
.fm-map-pin::before { content: ""; position: absolute; left: 50%; top: 50%; width: calc(var(--u) * 22); height: calc(var(--u) * 22); margin: calc(var(--u) * -11); border-radius: 50%; background: var(--on-accent); }
.fm-mark-paper { color: var(--on-paper); }
.fm-card { left: calc(var(--u) * 40); right: calc(var(--u) * 40); bottom: calc(var(--u) * 86); padding: calc(var(--u) * 40) calc(var(--u) * 44) calc(var(--u) * 30); border-radius: calc(var(--u) * 20); background: color-mix(in srgb, var(--paper) 94%, transparent); color: var(--on-paper); }
.fm-label-light { color: var(--accent-on-light); }
.fm-card-street { color: var(--on-paper); font-size: calc(var(--u) * 64); margin: calc(var(--u) * 18) 0 calc(var(--u) * 22); }
.fm-card li { display: flex; justify-content: space-between; align-items: baseline; padding: calc(var(--u) * 14) 0; border-top: calc(var(--u) * 2) solid color-mix(in srgb, var(--on-paper) 10%, transparent); font-size: calc(var(--u) * 32); white-space: nowrap; }
.fm-card-min { color: var(--accent-on-light); }
.fm-photo-blur img { filter: blur(3px); transform: scale(1.08); }
.fm-shade-over { inset: 0; background: color-mix(in srgb, var(--ink) 35%, transparent); }
.fm-extras { top: 34%; gap: calc(var(--u) * 34); }
.fm-extra { display: flex; align-items: center; gap: calc(var(--u) * 22); }
.fm-dash { display: block; width: calc(var(--u) * 28); height: calc(var(--u) * 3); background: var(--accent-on-dark); flex-shrink: 0; }
.fm-extra-text { font-size: calc(var(--u) * 58); }
.fk-map { background: var(--paper); }
.fk-map img { filter: grayscale(1) contrast(0.85); }
.fk-map-wash { position: absolute; inset: 0; background: color-mix(in srgb, var(--paper) 40%, transparent); }
.fk-map-pin { position: absolute; left: 50%; top: 50%; width: calc(var(--u) * 60); height: calc(var(--u) * 60); margin: calc(var(--u) * -30); border-radius: 50%; background: var(--accent); border: calc(var(--u) * 8) solid var(--paper); box-sizing: border-box; box-shadow: 0 8px 22px rgba(14,15,13,0.3); }
.fk-street { left: calc(var(--u) * 40); right: calc(var(--u) * 40); top: calc(var(--u) * 813); color: var(--on-paper); font-size: calc(var(--u) * 53); line-height: 1.1; white-space: nowrap; }
.fk-tiles-map { top: calc(var(--u) * 940); }
.fk-photo-dim::after { content: ""; position: absolute; inset: 0; background: rgba(14,15,13,0.35); }
.fk-photo-dim .fk-pill { z-index: 1; }
.fk-checks { left: calc(var(--u) * 40); right: calc(var(--u) * 40); top: calc(var(--u) * 813); display: grid; grid-template-columns: 1fr 1fr; gap: calc(var(--u) * 20); }
.fk-checks li { display: flex; align-items: center; gap: calc(var(--u) * 16); background: var(--paper); color: var(--on-paper); border-radius: calc(var(--u) * 27); padding: calc(var(--u) * 22); font-size: calc(var(--u) * 28); line-height: 1.15; min-width: 0; }
.fk-check { width: calc(var(--u) * 36); height: calc(var(--u) * 36); border-radius: calc(var(--u) * 10); background: var(--accent); color: var(--on-accent); font-size: calc(var(--u) * 24); display: grid; place-items: center; flex-shrink: 0; }
/* The same in 16:9 (film/src/parts_wide/NearbyMap and Extras, magazyn_wide, karta_wide). */
.film-frame-wide .ff-map-dot-1 { left: 22%; top: 30%; } .film-frame-wide .ff-map-dot-2 { left: 50%; top: 26%; } .film-frame-wide .ff-map-dot-3 { left: 48%; top: 70%; }
.film-frame-wide .ff-map-pin, .film-frame-wide .ff-map-label { left: 39%; top: 50%; }
.film-frame-wide .ff-map-list { left: auto; right: calc(var(--u) * 30); top: 50%; bottom: auto; width: calc(var(--u) * 430); transform: translateY(-50%); gap: calc(var(--u) * 18); font-size: calc(var(--u) * 32); }
.film-frame-wide .ff-map-number { width: calc(var(--u) * 42); height: calc(var(--u) * 42); font-size: calc(var(--u) * 22); }
.film-frame-wide .ff-extras-label { top: calc(var(--u) * 150); font-size: calc(var(--u) * 52); }
.film-frame-wide .ff-extras { top: calc(var(--u) * 240); right: auto; width: calc(var(--u) * 620); gap: calc(var(--u) * 26); }
.film-frame-wide .ff-extras li { font-size: calc(var(--u) * 38); }
.film-frame-wide .ff-check { width: calc(var(--u) * 44); height: calc(var(--u) * 44); }
.film-frame-wide .fm-map-pin { left: 33%; top: 50%; }
.film-frame-wide .fm-card { left: auto; right: calc(var(--u) * 56); bottom: auto; top: 50%; width: calc(var(--u) * 480); transform: translateY(-50%); padding: calc(var(--u) * 36) calc(var(--u) * 40) calc(var(--u) * 26); }
.film-frame-wide .fm-card-street { font-size: calc(var(--u) * 46); margin: calc(var(--u) * 16) 0 calc(var(--u) * 18); }
.film-frame-wide .fm-card li { font-size: calc(var(--u) * 26); padding: calc(var(--u) * 13) 0; }
.film-frame-wide .fm-extras { top: calc(var(--u) * 150); gap: calc(var(--u) * 30); }
.film-frame-wide .fm-extra-text { font-size: calc(var(--u) * 50); }
.film-frame-wide .fk-street { left: calc(var(--u) * 820); right: calc(var(--u) * 40); top: calc(var(--u) * 80); font-size: calc(var(--u) * 38); white-space: normal; }
.film-frame-wide .fk-tiles-map { left: calc(var(--u) * 820); right: calc(var(--u) * 40); top: calc(var(--u) * 230); }
.film-frame-wide .fk-checks { left: calc(var(--u) * 820); right: calc(var(--u) * 40); top: calc(var(--u) * 60); grid-template-columns: 1fr; gap: calc(var(--u) * 14); }
.film-frame-wide .fk-checks li { padding: calc(var(--u) * 16) calc(var(--u) * 20); border-radius: calc(var(--u) * 22); font-size: calc(var(--u) * 26); }
.film-frame-wide .fk-check { width: calc(var(--u) * 34); height: calc(var(--u) * 34); font-size: calc(var(--u) * 22); }
/* Spacer: the room fills the frame (film/src/spacer/Shot.tsx). */
.fs-photo { inset: 0; }
.fs-photo img { width: 100%; height: 100%; object-fit: cover; }
.fs-photo::after { content: ""; position: absolute; inset: auto 0 0 0; height: 34%; background: linear-gradient(to bottom, transparent, rgb(14 15 13 / 0.7)); }
.fs-sticker { top: calc(var(--u) * 922); }

/* The status bar along the top edge of the preview's stage (reels/studio/preview_state) takes room above the film
   instead of covering it. From xl the film's frame takes its height from the stage and its width from the shape. */
@media (width >= 80rem) {
  .studio-preview-film {
    aspect-ratio: 9 / 16;
  }

  .studio[data-shape="wide"] .studio-preview-film {
    aspect-ratio: 16 / 9;
  }

  .studio-preview-stage:has(.studio-preview-state) {
    padding-top: 4.5rem;
  }

  .studio-preview-stage:has(.studio-preview-state) .studio-preview-chip {
    top: 5.25rem;
  }
}

/* The film's shape in the studio (shape_controller.js, `data-shape` on .studio): what is for one shape only shows
   with it (the file played, its download), and the frame without a film follows it. */
[data-controller~="shape"][data-shape="wide"] .only-vertical,
[data-controller~="shape"]:not([data-shape="wide"]) .only-wide {
  display: none;
}

.film-shape {
  aspect-ratio: 9 / 16;
}

.studio[data-shape="wide"] .film-shape {
  aspect-ratio: 16 / 9;
}

/* While a stage is being made the film is covered (film_busy_tag) and its controls are out of reach. */
.studio-preview-film:has(.film-busy) ~ .film-controls {
  pointer-events: none;
  opacity: 0.35;
}

/* Scrolling inside the studio (the form, Asystent, the versions): a thin bar on a clear track instead of the
   browser's wide grey one. `scrollbar-color` is inherited, `scrollbar-width` is not. In the base layer, so a scroller
   that hides its bar on purpose (the film-order strip: [scrollbar-width:none], it has its arrows and dots) keeps it
   hidden — an unlayered rule here would beat every utility. */
@layer base {
  .studio {
    scrollbar-color: color-mix(in srgb, var(--color-base-content) 22%, transparent) transparent;
  }

  .studio * {
    scrollbar-width: thin;
  }
}

/* The steps column (≥ xl) names each step under its mark, so the pills' "name · sentence" tooltip shows only on the
   narrow pills (reels/studio/_steps). */
@media (width >= 80rem) {
  .studio-step-tip::before,
  .studio-step-tip::after {
    display: none;
  }
}

/* On a touch screen a tap leaves the pill "hovered" until the next tap elsewhere, so DaisyUI's tooltip would stay up
   after choosing a step. There it shows only while the finger is down (a long press); a mouse keeps its hover. */
@media (hover: none) {
  .studio-step-tip:not(:active)::before,
  .studio-step-tip:not(:active)::after {
    opacity: 0;
  }
}

/* The app menu (layouts/sidebar, sidebar_controller.js): full, or from lg collapsed (`data-collapsed`) to an icon rail
   where each item is its icon and its label a tooltip. The rail's own parts (.app-menu-rail) show only in the rail,
   the full menu's (.app-menu-full) only in the full menu, and the tooltips only in the rail. Below lg (the drawer on a
   phone) it is always full. Outside the layers: these override the menu's utility classes. */
.app-menu:not([data-collapsed]) .app-menu-rail,
.app-menu:not([data-collapsed]) .tooltip::before,
.app-menu:not([data-collapsed]) .tooltip::after {
  display: none;
}

@media (width < 64rem) {
  .app-menu .app-menu-rail,
  .app-menu .tooltip::before,
  .app-menu .tooltip::after {
    display: none;
  }
}

@media (width >= 64rem) {
  .app-menu[data-collapsed] {
    width: 4rem;
    align-items: center;
    gap: 1.25rem;
    padding-inline: 0;

    .app-menu-full,
    .app-menu-label {
      display: none;
    }

    .app-menu-head {
      flex-direction: column;
      gap: 0.75rem;
      padding: 0;
    }

    nav,
    .app-menu-foot {
      align-items: center;
    }

    .app-menu-foot {
      gap: 0.25rem;
      padding-inline: 0;
    }

    .nav-item {
      width: 2.5rem;
      height: 2.5rem;
      margin-inline: 0;
      padding: 0;
      justify-content: center;
    }

    .app-menu-accent {
      width: 2.5rem;
      height: 2.5rem;
      padding: 0;
      justify-content: center;
    }
  }

  /* The drawer's side scrolls, which would clip the rail's tooltips; the rail fits the window. */
  .drawer-side:has(> .app-menu[data-collapsed]) {
    overflow: visible;
  }
}

/* The film page as a full-screen studio (layouts/studio, reels/show): the window's height, in rows of the top bar, the
   middle and the bottom bar. The workspace and the panel's wrapper have no box of their own (`contents`), so their
   parts are cells of this grid; below xl the middle is the studio's views side by side, one on show. The ⋯ menu sits outside the broadcast workspace and over the top bar's right end. A page without Asystent
   (an entered admin) hides its toggle. */
.studio {
  display: grid;
  flex: 1;
  min-height: 0;
  grid-template-columns: minmax(0, 1fr) auto minmax(auto, 1fr);
  grid-template-rows: auto minmax(0, 1fr) auto;
  /* A step's tooltip at the window's edge would widen the page. */
  overflow-x: clip;
}

/* The top bar's row: the way back and the title, the steps (reels/studio/steps: pills here below xl, centred in the
   row while the title and the toggles leave room, a column on the left from xl) and the Wersje and Asystent toggles. */
.studio-top-bar {
  grid-area: 1 / 1 / 2 / 2;
}

.studio-steps {
  grid-area: 1 / 2 / 2 / 3;
}

.studio-top-end {
  grid-area: 1 / 3 / 2 / 4;
}

/* A film nobody may delete has the ⋯ menu below xl only, for "Zobacz ogłoszenie" (reels/show). */
.studio:has(> .studio-menu:not(.studio-menu-narrow)) .studio-top-end {
  padding-right: 3.5rem;
}

.studio-menu {
  grid-area: 1 / 1 / 2 / -1;
  align-self: center;
  justify-self: end;
  margin-right: 0.75rem;
}

/* The scrollers (the drawer, the preview below xl) are positioned, so absolutely placed bits inside them (.sr-only
   labels in the listing's facts) stay in their scroll and never make the page itself scroll. The workspace has no box
   of its own: its parts are cells of the studio's grid. */
.studio-drawer {
  position: relative;
}

.studio-workspace {
  display: contents;
}

/* The ✦ button that opens Asystent as a bubble (film_styles/assistant_panel) gives way to the open bubble. */
:has(> #assistant_panel:not([hidden])) > .assistant-fab {
  display: none;
}

/* The bottom bar (reels/studio/bar) spans the studio under the middle and Asystent, always at the window's bottom.
   "Popraw ręcznie" shows while the drawer is closed, its "Schowaj" mirror while it is open: in the bar below xl; from
   xl the step on show in the steps column opens and hides it (step_form_tag). */
.studio-bar {
  grid-area: 3 / 1 / 4 / -1;
  min-width: 0;
}

.studio-bar-close,
.studio-step-close,
.studio:has(.studio-drawer[data-open]) :is(.studio-bar-open, [aria-current="step"] .studio-step-open) {
  display: none;
}

.studio:has(.studio-drawer[data-open]) :is(.studio-bar-close, .studio-step-close) {
  display: contents;
}

/* The step's form in the drawer (drawer_controller.js), open by default ("Schowaj" hides it, "Popraw ręcznie" shows it).
   On a wide screen it is the work area with a scroll of its own, the preview narrowed beside it and Asystent as the
   agent left it (its column, or minimised to the ✦ strip). Below xl the form is the Popraw view. The listing in review is the form itself, open by the server's say. Outside the layers: these override the
   layout's utility classes. */
.studio-drawer:not([data-open]),
.assistant-strip,
.assistant-fold {
  display: none;
}

.studio-drawer[data-open] {
  animation: studio-drawer-in 180ms ease-out;
}

@keyframes studio-drawer-in {
  from {
    opacity: 0;
    transform: translateX(-1.5rem);
  }
}

@media (prefers-reduced-motion: reduce) {
  .studio-drawer[data-open] {
    animation: none;
  }
}

/* The film's path as a strip on top of the listing form (reels/stages/listing/film_path, `strip`): smaller tiles and
   arrows, so 5–7 screens show side by side on a laptop; the rest scrolls sideways. */
.film-path-strip {
  .film-path-tile {
    width: 10rem;
  }

  .film-path-arrow {
    width: 1.75rem;
    height: calc(10rem * 16 / 9);
  }

  .carousel-dashes {
    margin-top: 0.5rem;
  }
}

/* The trial demo (demos/working, demos/done). The film's progress as a ring filled in the accent up to
   --progress (progress_ring_tag). */
.progress-ring {
  @apply mb-6 grid size-33 place-items-center rounded-full;
  background: conic-gradient(var(--color-accent) 0 var(--progress), var(--color-base-300) var(--progress) 100%);
}

.progress-ring-value {
  @apply grid size-27 place-items-center rounded-full bg-base-100 text-3xl font-extrabold tabular-nums;
}

/* The phone every film plays in (iphone_tag), ported from zento.pl's RolkaPhone: a 9:19.5 body with a thin titanium
   edge, the island floating over the screen, a status bar above the 9:16 film and the home indicator under it. */
.iphone {
  position: relative;
  width: min(300px, 74vw);
  aspect-ratio: 9 / 19.5;
  padding: 7px;
  border-radius: 46px;
  background: linear-gradient(145deg, #5b5c55, #1b1c17 30%, #2e2f29 70%, #6a6b63);
  box-shadow: inset 0 0 0 1.5px rgb(255 255 255 / 0.14), 0 50px 90px -40px rgb(20 24 16 / 0.75);
}

.iphone-btn { position: absolute; width: 3px; background: #2b2c26; border-radius: 2px; }
.iphone-btn.a { left: -3px; top: 17%; height: 4.5%; }
.iphone-btn.b { left: -3px; top: 25%; height: 8%; }
.iphone-btn.c { left: -3px; top: 35%; height: 8%; }
.iphone-btn.d { right: -3px; top: 29%; height: 12%; }

.iphone-screen {
  position: relative;
  display: grid;
  align-items: center;
  width: 100%;
  height: 100%;
  overflow: hidden;
  border-radius: 39px;
  background: #000;
}

.iphone-screen::before {
  content: "";
  position: absolute;
  z-index: 3;
  top: 11px;
  left: 50%;
  width: 31%;
  height: 25px;
  border-radius: 20px;
  background: #000;
  box-shadow: inset 0 0 0 1px rgb(255 255 255 / 0.05);
  transform: translateX(-50%);
}

.iphone-status {
  position: absolute;
  z-index: 2;
  inset: 0 0 auto 0;
  display: flex;
  align-items: center;
  justify-content: space-between;
  height: 9%;
  padding: 0 9% 0 11%;
  color: #fff;
  font-size: 0.86rem;
  font-weight: 700;
  letter-spacing: -0.01em;
}

.iphone-icons { display: flex; align-items: center; gap: 5px; }
.iphone-icons svg { height: 11px; fill: currentColor; }

.iphone-home {
  position: absolute;
  z-index: 2;
  bottom: 9px;
  left: 50%;
  width: 36%;
  height: 5px;
  border-radius: 3px;
  background: rgb(255 255 255 / 0.85);
  transform: translateX(-50%);
}

/* The 9:16 film area between the status bar and the home indicator: a <video> or a film frame fills it. The video gets
   no focus ring, so no coloured line shows at its edges once it has been clicked. */
.iphone-film { position: relative; width: 100%; aspect-ratio: 9 / 16; overflow: hidden; background: #000; }
.iphone-film > video { display: block; width: 100%; height: 100%; object-fit: cover; background: #000; }
.iphone video,
.iphone video:focus,
.iphone video:focus-visible { outline: none; }
/* A template's intro frame over a film without a poster (iphone_film_tag's cover), gone once the film plays. */
.iphone-cover { position: absolute; inset: 0; }
.iphone-cover[hidden] { display: none; }

/* The film opens on a pale ident, where the browser's own play button is lost: this one cannot be missed. */
.iphone-play {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  width: 96px;
  height: 96px;
  margin: auto;
  border-radius: 50%;
  background: var(--color-accent);
  color: var(--color-accent-content);
  cursor: pointer;
  box-shadow: 0 14px 40px -10px rgb(0 0 0 / 0.6);
  transition: transform 0.25s ease;
}

.iphone-play:hover,
.iphone-play:focus-visible { transform: scale(1.07); }
.iphone-play[hidden] { display: none; }
.iphone-play-icon { width: 44px; height: 44px; transform: translateX(3px); fill: currentColor; stroke: none; }

/* Slides taking turns (rotating_slides_tag): stacked in one cell, the one on show (data-active) faded in; the dots
   under them, the current one longer and white. */
.rotation-slide {
  @apply invisible opacity-0 transition-[opacity,visibility] duration-500 [grid-area:1/1];
}

.rotation-slide[data-active] {
  @apply visible opacity-100;
}

.rotation-dot {
  @apply h-1.5 w-6.5 cursor-pointer rounded-full bg-[#3a3a31] transition-all;
}

.rotation-dot[aria-current="true"] {
  @apply w-11 bg-paper;
}

/* Below xl the studio is one column of rows: the top bar, the steps and the switch of its views under them (one header
   block, the same gutters), the middle and the bottom bar. The middle is four views side by side in the switch's order
   (reels/studio/views, views_controller.js): the film (.studio-preview), the step's form (the drawer, open or not),
   Asystent and the step's versions, the one on show (data-mobile-view on .studio) in place and the others off to its
   left or right; changing view slides the track toward the chosen one. In Asystent its composer is the bottom area, in
   the other views the bar with the step's decisions. The "Więcej" menus open as a sheet from the bottom. */
@media (width < 80rem) {
  .studio {
    grid-template-columns: minmax(0, 1fr);
    grid-template-rows: auto auto auto minmax(0, 1fr) auto;
  }

  .studio-top-bar {
    grid-area: 1 / 1 / 2 / -1;
  }

  .studio:has(> .studio-menu) .studio-top-bar {
    padding-right: 3.5rem;
  }

  .studio-steps {
    grid-area: 2 / 1 / 3 / -1;
    justify-content: center;
  }

  .studio-views {
    grid-area: 3 / 1 / 4 / -1;
    container-type: inline-size;
  }

  /* Four tabs that would squeeze their labels: each its icon over its label. */
  @container (width < 26rem) {
    .studio-views:has(.studio-view-tab:nth-child(4)) .studio-view-tab {
      flex-direction: column;
      gap: 0.125rem;
      padding-block: 0.3125rem;
      font-size: 0.6875rem;
    }
  }

  .studio-errors {
    grid-area: 4 / 1 / 5 / -1;
    z-index: 30;
    align-self: start;
    margin: 0.75rem;
  }

  .studio-bar {
    grid-area: 5 / 1 / 6 / -1;
  }

  .studio[data-mobile-view="assistant"] .studio-bar {
    display: none;
  }

  /* The views: each fills the middle and scrolls inside itself (Asystent and the versions in their own lists, shown by
     their controllers when their view is: views:shown). */
  .studio-preview,
  .studio-drawer,
  .studio #assistant_panel,
  .studio .studio-versions {
    grid-area: 4 / 1 / 5 / -1;
    min-height: 0;
    transform: translateX(100%);
    opacity: 0;
    visibility: hidden;
    transition: transform 250ms ease, opacity 250ms ease, visibility 0s linear 250ms;
  }

  .studio-preview,
  .studio-drawer {
    overflow-y: auto;
    overscroll-behavior: contain;
  }

  .studio[data-mobile-view="film"] .studio-preview,
  .studio[data-mobile-view="form"] .studio-drawer,
  .studio[data-mobile-view="assistant"] #assistant_panel,
  .studio[data-mobile-view="versions"] .studio-versions {
    transform: none;
    opacity: 1;
    visibility: visible;
    transition: transform 250ms ease, opacity 250ms ease, visibility 0s;
  }

  .studio:is([data-mobile-view="form"], [data-mobile-view="assistant"], [data-mobile-view="versions"]) .studio-preview,
  .studio:is([data-mobile-view="assistant"], [data-mobile-view="versions"]) .studio-drawer,
  .studio[data-mobile-view="versions"] #assistant_panel {
    transform: translateX(-100%);
  }

  @media (prefers-reduced-motion: reduce) {
    .studio .studio-preview,
    .studio .studio-drawer,
    .studio #assistant_panel,
    .studio .studio-versions {
      transition: none !important;
    }
  }

  /* Popraw: the step's form scrolling in its view, open or not (a step with no form has no view), the peek on top. */
  .studio-drawer:not([data-drawer-force="closed"]) {
    display: flex;
  }

  .studio-drawer {
    padding: 0.75rem 0.75rem 1.5rem;
    background: var(--color-base-200);
  }

  .studio-drawer,
  .studio-drawer[data-open] {
    animation: none;
  }

  /* Film: the stage edge to edge, the phone as tall as the room left under the chip and over its controls (and the
     map credit), centred, its controls as wide as it so the scrub bar has its room. The listing being read, or that
     could not be read, keeps a margin. */
  .studio-preview:has(.studio-preview-box) {
    gap: 0;
    background: var(--color-neutral);
  }

  .studio-preview:not(:has(.studio-preview-box)) {
    padding: 1.5rem 0.75rem;
  }

  .studio-preview-box:has(> .studio-preview-chip) {
    padding-top: 2.75rem;
  }

  .studio-preview-player {
    container-type: size;
    min-height: 20rem;
  }

  /* Below xl the film is as wide as the room under the steps allows, in its shape. */
  .studio-preview-film {
    aspect-ratio: 9 / 16;
  }

  .studio-preview-film,
  .studio-preview-player > .film-controls {
    width: min(100cqw, calc((100cqh - 4rem) * 9 / 16));
  }

  .studio[data-shape="wide"] .studio-preview-film {
    aspect-ratio: 16 / 9;
  }

  .studio[data-shape="wide"] .studio-preview-film,
  .studio[data-shape="wide"] .studio-preview-player > .film-controls {
    width: min(100cqw, calc((100cqh - 4rem) * 16 / 9));
  }

  .studio-preview-side {
    padding: 1.25rem 0.75rem;
    background: var(--color-base-100);
  }

  /* The peek played: the film over the whole page while it plays (film_controls_controller.js marks it), "Wróć" in
     its top-left corner in place of the chip; "Wróć", a pause or the phone's back gives the form back (views#unpeek). */
  .studio[data-mobile-view="form"][data-peeking]:has(.film-controls[data-playing]) {
    .studio-preview {
      position: fixed;
      inset: 0;
      z-index: 70;
      padding: env(safe-area-inset-top) 0 env(safe-area-inset-bottom);
      transform: none;
      opacity: 1;
      visibility: visible;
      transition: none;
    }

    .studio-preview-box {
      padding-top: 4rem;
    }

    .studio-preview-chip {
      display: none;
    }
  }

  .studio[data-mobile-view="form"][data-peeking]:has(.film-controls[data-playing]) .studio-peek-back {
    display: flex;
  }

  /* The bottom bar (reels/studio/bar) in two rows, never scrolling sideways: the step's name and its sentence on one
     line; a break (::after); the step's buttons, the main one across the width, the secondary ones as icons and the
     rarer ones under "Więcej". While an earlier step is on show the current step's approval comes first, the ⋯ after
     it. The form's own buttons ("Popraw ręcznie", "Schowaj") are the switch's Popraw here. */
  .studio-bar {
    row-gap: 0;
  }

  .studio-bar-drawer {
    display: none;
  }

  .studio-bar-what {
    display: flex;
    align-items: baseline;
    gap: 0.375rem;

    > :first-child {
      flex-shrink: 0;
    }

    > :last-child {
      min-width: 0;
    }

    > :last-child::before {
      content: "· ";
    }
  }

  .studio-bar::after {
    content: "";
    order: 1;
    flex-basis: 100%;
  }

  .studio-bar-actions,
  .studio-bar-ahead {
    order: 2;
    flex: 1 1 auto;
    margin-top: 0.5rem;
  }

  .studio-bar-actions:not(:has(*)) {
    display: none;
  }

  .studio-bar:has(> .studio-bar-ahead) .studio-bar-actions {
    order: 3;
    flex: none;
  }

  /* "Więcej" (the bar's and the top bar's, .studio-sheet): DaisyUI's dropdown, open while focus is inside it, as a
     sheet from the bottom over the dimmed page (its ::before, a tap on it closes, sheet_controller.js), a handle on top
     and full-width rows with their icons. Its closed content stays DaisyUI's (display: none). */
  .studio-sheet:focus-within::before {
    content: "";
    position: fixed;
    inset: 0;
    z-index: 90;
    background: rgb(16 16 9 / 0.45);
    animation: studio-fade-in 200ms ease-out;
  }

  .studio-sheet > .dropdown-content {
    position: fixed;
    inset: auto 0 0;
    z-index: 91;
    width: auto;
    max-height: min(80dvh, 32rem);
    overflow-y: auto;
    margin: 0;
    translate: none;
    border: 0;
    border-radius: 1.375rem 1.375rem 0 0;
    padding: 0.25rem 0.875rem max(1.25rem, env(safe-area-inset-bottom));
    box-shadow: 0 -10px 30px rgb(16 16 9 / 0.2);
  }

  .studio-sheet:focus-within > .dropdown-content {
    animation: studio-sheet-in 250ms ease-out;
  }

  /* Its trigger stays under the dimmed page, without a focus ring over it. */
  .studio-sheet:focus-within > [role="button"] {
    outline: none;
  }

  .studio-sheet-handle {
    display: grid;
    place-items: center;
    width: 100%;
    height: 1.75rem;
    cursor: pointer;
  }

  .studio-sheet-handle::before {
    content: "";
    width: 2.5rem;
    height: 0.3125rem;
    border-radius: 0.25rem;
    background: color-mix(in srgb, var(--color-base-content) 28%, transparent);
  }

  /* The rows (the menu's own items); the blocked step's help box inside it keeps its buttons as they are. */
  .studio-sheet > .dropdown-content > div > :is(.button, [role="status"]),
  .studio-sheet > .dropdown-content > div > form > .button {
    justify-content: flex-start;
    width: 100%;
  }

  .studio-sheet > .dropdown-content > div > .button,
  .studio-sheet > .dropdown-content > div > form > .button {
    min-height: 3rem;
    gap: 0.75rem;
    font-size: 0.9375rem;
    font-weight: 500;
    background: transparent;
  }

  .studio-sheet > .dropdown-content > div > .button:hover,
  .studio-sheet > .dropdown-content > div > form > .button:hover {
    background: var(--color-base-200);
  }

  @media (prefers-reduced-motion: reduce) {
    .studio-sheet:focus-within::before,
    .studio-sheet:focus-within > .dropdown-content {
      animation: none;
    }
  }
}

@keyframes studio-sheet-in {
  from {
    transform: translateY(100%);
  }
}

@keyframes studio-fade-in {
  from {
    opacity: 0;
  }
}

/* From xl the middle is one row of columns under the top bar, each as tall as the row and scrolling inside itself,
   after the steps' column on the left:
   - the preview, then Asystent (no form on the step on show, or the form hidden);
   - the listing in review: its form as the work area (the film's path a strip on its top), then Asystent;
   - the step's form open (by default): the form as the work area, the preview narrowed, then Asystent (its column or
     the ✦ strip);
   Asystent never goes away here: closed (its header's ✦, the top bar's toggle) it is the ✦ strip, also beside a
   step's open versions. Only a page without it (an entered admin) gives its column away, unless the versions take it. The zero-width end column gives the row its right gutter. The top
   bar spans the row, the Asystent toggle over its end. */
/* From xl the bottom bar's ⋯ menu (bar_menu_tag) has no box, over DaisyUI's closed dropdown: its buttons stand in the
   row. The top bar's ⋯ menu of a film nobody may delete holds nothing here. */
@media (width >= 80rem) {
  .studio-bar-more,
  .studio-bar-more > .dropdown-content,
  .studio-bar-menu-list {
    display: contents;
  }

  .studio-menu-narrow {
    display: none;
  }
}

@media (width >= 80rem) {
  .studio {
    gap: 0.875rem;
    grid-template-columns: 6rem minmax(0, 1fr) 25rem 0;
    grid-template-areas: "top top top top" "steps preview assistant ." "bar bar bar bar";
  }

  .studio-top-bar {
    grid-area: 1 / 1 / 2 / -1;
  }

  .studio-top-end {
    grid-area: 1 / 1 / 2 / -1;
    justify-self: end;
  }

  .studio-steps {
    grid-area: steps;
  }

  /* The steps' column (reels/studio/steps): the steps a pitch apart, one track behind their marks from the first
     mark's centre to the last's, filled with the accent down to the film's step (--progress on the nav). The colours
     here win over the pills' utilities (below xl), being outside Tailwind's layers. */
  .studio-steps {
    --step-height: 4.75rem;
    --step-gap: 1.25rem;
    --step-pitch: calc(var(--step-height) + var(--step-gap));
    --step-soft: color-mix(in srgb, var(--color-accent) 18%, var(--color-base-100));

    ol {
      position: relative;
      isolation: isolate;
      gap: var(--step-gap);
    }

    ol::before,
    ol::after {
      content: "";
      position: absolute;
      z-index: -1;
      top: 1rem;
      left: calc(50% - 1px);
      width: 2px;
      border-radius: 1px;
    }

    ol::before {
      height: calc((var(--steps) - 1) * var(--step-pitch));
      background: var(--color-hairline);
    }

    ol::after {
      height: calc(var(--progress) * var(--step-pitch));
      background: var(--color-accent);
    }

    .studio-step {
      height: var(--step-height);
    }

    .studio-step-pill {
      border-radius: var(--radius-field);
    }

    .studio-step-pill:focus-visible {
      outline: 2px solid var(--color-accent-ink);
      outline-offset: 2px;
    }

    .studio-step-mark {
      font-size: 0.75rem;
      font-weight: 600;
      background: var(--color-base-100);
      color: var(--color-muted);
      box-shadow: inset 0 0 0 1px var(--color-hairline);
      transition: transform 120ms ease-out, box-shadow 120ms ease-out;
    }

    .studio-step-mark > * {
      color: inherit;
    }

    [data-state="stale"] .studio-step-mark {
      color: var(--color-accent-ink);
      box-shadow: inset 0 0 0 1px var(--color-accent);
    }

    [data-state="current"] .studio-step-mark {
      background: var(--color-base-content);
      color: var(--color-base-100);
      box-shadow: 0 0 0 3px var(--step-soft);
    }

    [data-marker="locked"] .studio-step-mark {
      background: var(--step-soft);
      color: var(--color-accent-ink);
      box-shadow: none;
    }

    [data-marker="done"] .studio-step-mark {
      background: var(--color-accent);
      color: var(--color-base-100);
      box-shadow: none;
    }

    [data-marker="failed"] .studio-step-mark {
      background: var(--color-base-100);
      color: var(--color-error);
      box-shadow: inset 0 0 0 2px var(--color-error), 0 0 0 3px color-mix(in srgb, var(--color-error) 15%, transparent);
    }

    :is(a, button).studio-step-pill:hover .studio-step-mark {
      transform: translateY(-1px);
      box-shadow: inset 0 0 0 2px var(--color-accent-ink), 0 2px 6px color-mix(in srgb, var(--color-base-content) 12%, transparent);
    }

    /* The film's step and a failed one keep their ring on hover, darkened. */
    [data-state="current"] :is(a, button).studio-step-pill:hover .studio-step-mark {
      box-shadow: 0 0 0 3px color-mix(in srgb, var(--color-accent) 45%, var(--color-base-100));
    }

    [data-marker="failed"] :is(a, button).studio-step-pill:hover .studio-step-mark {
      box-shadow: inset 0 0 0 2px var(--color-error), 0 0 0 3px color-mix(in srgb, var(--color-error) 35%, transparent);
    }

    .studio-step-name {
      display: -webkit-box;
      -webkit-box-orient: vertical;
      -webkit-line-clamp: 2;
      overflow: hidden;
      max-width: 100%;
      padding: 0.125rem 0.375rem;
      border-radius: 0.5rem;
      font-size: 0.75rem;
      line-height: 1rem;
      text-align: center;
      color: var(--color-muted);
      background: var(--color-base-200);
    }

    [aria-current="step"] .studio-step-name {
      font-weight: 700;
      color: var(--color-base-content);
      background: var(--color-base-100);
    }
  }

  .studio-preview {
    grid-area: preview;
    min-height: 0;
  }

  /* A step's versions (reels/studio/versions_panel) open in Asystent's place, Asystent hidden meanwhile: its column as
     wide as Asystent open and unfolded (even when Asystent is closed or folded). Closing them gives the place back as
     Asystent was. */
  .studio:has(.studio-versions:not([hidden])) #assistant_panel {
    display: none;
  }

  .studio #assistant_panel,
  .studio .studio-versions {
    grid-area: assistant;
  }

  .studio-errors {
    grid-area: 2 / 2 / 3 / -2;
    z-index: 30;
    align-self: start;
    justify-self: center;
    margin-top: 0.75rem;
    border-radius: var(--radius-field);
    background: var(--color-base-100);
    box-shadow: 0 10px 30px rgb(16 16 9 / 0.15);

    > [role="alert"] {
      margin: 0;
    }
  }

  .studio:has(.studio-drawer[data-open]) {
    grid-template-areas: "top top top top top" "steps work preview assistant ." "bar bar bar bar bar";
  }

  .studio:has(.studio-drawer[data-open][data-drawer-force="open"]) {
    grid-template-columns: 6rem minmax(0, 1fr) 22.5rem 0;
    grid-template-areas: "top top top top" "steps work assistant ." "bar bar bar bar";
  }

  .studio:has(#assistant_panel[hidden]):not(:has(.studio-versions:not([hidden]))):has(.studio-drawer[data-open][data-drawer-force="open"]) {
    grid-template-columns: 6rem minmax(0, 1fr) 3.25rem 0;
  }

  .studio:has(.studio-drawer[data-open]:not([data-drawer-force="open"])) {
    grid-template-columns: 6rem minmax(0, 1fr) 23.75rem 22.5rem 0;

    .studio-preview-stage {
      padding: 0.875rem;
    }

    .studio-preview-side {
      display: none;
    }
  }

  .studio:has(#assistant_panel[hidden]):not(:has(.studio-versions:not([hidden]))):has(.studio-drawer[data-open]:not([data-drawer-force="open"])) {
    grid-template-columns: 6rem minmax(0, 1fr) 23.75rem 3.25rem 0;
  }

  .studio:has(#assistant_panel[hidden]):not(:has(.studio-versions:not([hidden]), .studio-drawer[data-open])) {
    grid-template-columns: 6rem minmax(0, 1fr) 3.25rem 0;
  }

  .studio:not(:has(#assistant_panel, .studio-versions:not([hidden]))) {
    grid-template-columns: 6rem minmax(0, 1fr) 0;
    grid-template-areas: "top top top" "steps preview ." "bar bar bar";
  }

  .studio:not(:has(#assistant_panel, .studio-versions:not([hidden]))):has(.studio-drawer[data-open]) {
    grid-template-columns: 6rem minmax(0, 1fr) 23.75rem 0;
    grid-template-areas: "top top top top" "steps work preview ." "bar bar bar bar";
  }

  .studio:not(:has(#assistant_panel, .studio-versions:not([hidden]))):has(.studio-drawer[data-open][data-drawer-force="open"]) {
    grid-template-columns: 6rem minmax(0, 1fr) 0;
    grid-template-areas: "top top top" "steps work ." "bar bar bar";
  }

  .studio-drawer[data-open] {
    grid-area: work;
    min-height: 0;
    overflow-y: auto;
    overscroll-behavior: contain;
  }

  /* The header's ✦ folds Asystent in place of its mark. Folded (closed, or while the drawer is open),
     the ✦ strip beside the hidden panel takes its cell, unless a step's versions are open in it. */
  .studio #assistant_panel {
    .assistant-mark {
      display: none;
    }

    .assistant-fold {
      display: inline-flex;
    }
  }

  .studio:has(#assistant_panel[hidden]) .assistant-strip,
  .studio:has(.studio-versions:not([hidden])) .assistant-strip {
    grid-area: assistant;
    display: flex;
    justify-content: center;
    padding-top: 1.25rem;
    border: 1px solid var(--color-hairline);
    border-radius: 1rem;
    background: var(--color-base-100);
    color: var(--color-accent-ink);
    cursor: pointer;
  }

  .studio .assistant-strip:hover {
    background: var(--color-base-200);
  }

  /* A step's versions open in Asystent's column, Asystent folded to the ✦ strip beside them (its click closes them). */
  .studio:has(#assistant_panel):has(.studio-versions:not([hidden])) .assistant-strip {
    grid-area: strip;
  }

  .studio:has(#assistant_panel):has(.studio-versions:not([hidden])) {
    grid-template-columns: 6rem minmax(0, 1fr) 25rem 3.25rem 0;
    grid-template-areas: "top top top top top" "steps preview assistant strip ." "bar bar bar bar bar";
  }

  .studio:has(#assistant_panel):has(.studio-versions:not([hidden])):has(.studio-drawer[data-open]) {
    grid-template-columns: 6rem minmax(0, 1fr) 23.75rem 22.5rem 3.25rem 0;
    grid-template-areas: "top top top top top top" "steps work preview assistant strip ." "bar bar bar bar bar bar";
  }

  .studio:has(#assistant_panel):has(.studio-versions:not([hidden])):has(.studio-drawer[data-open][data-drawer-force="open"]) {
    grid-template-columns: 6rem minmax(0, 1fr) 22.5rem 3.25rem 0;
    grid-template-areas: "top top top top top" "steps work assistant strip ." "bar bar bar bar bar";
  }
}

/* Between xl and 2xl the form keeps its width (about 460px at 1280px): beside it the preview narrows to 18rem and
   Asystent (or a step's versions) to 20rem. The rules repeat those above in their order, columns only. */
@media (80rem <= width < 96rem) {
  .studio:has(.studio-drawer[data-open][data-drawer-force="open"]) {
    grid-template-columns: 6rem minmax(0, 1fr) 20rem 0;
  }

  .studio:has(.studio-drawer[data-open]:not([data-drawer-force="open"])) {
    grid-template-columns: 6rem minmax(0, 1fr) 18rem 20rem 0;
  }

  .studio:has(#assistant_panel[hidden]):not(:has(.studio-versions:not([hidden]))):has(.studio-drawer[data-open]:not([data-drawer-force="open"])) {
    grid-template-columns: 6rem minmax(0, 1fr) 18rem 3.25rem 0;
  }

  .studio:not(:has(#assistant_panel, .studio-versions:not([hidden]))):has(.studio-drawer[data-open]) {
    grid-template-columns: 6rem minmax(0, 1fr) 18rem 0;
  }

  .studio:has(#assistant_panel):has(.studio-versions:not([hidden])):has(.studio-drawer[data-open]) {
    grid-template-columns: 6rem minmax(0, 1fr) 18rem 20rem 3.25rem 0;
  }

  .studio:has(#assistant_panel):has(.studio-versions:not([hidden])):has(.studio-drawer[data-open][data-drawer-force="open"]) {
    grid-template-columns: 6rem minmax(0, 1fr) 20rem 3.25rem 0;
  }
}
