/* Dalal El Fachtali — site styles. Tokens first; everything else uses them. */
:root{
  --bg:#F6F3EE;
  --panel:#EDE8E0;
  --panel-soft:#F1ECE4;
  --ink:#191713;
  --ink-soft:#2B2721;
  --muted:#6E6659;
  --faint:#9A9082;
  --line:#E1DACE;
  --accent:#2E5E86;        /* petrol blue, sampled from Le Souffle */
  --accent-deep:#1E4463;   /* hover and pressed states */
  --frame:#C9BFAE;         /* 1.64:1 on the ground: a whisper, not a line */
  --frame-w:1px;
  --serif:'EB Garamond',Georgia,'Times New Roman',serif;
  --sans:'Karla',system-ui,-apple-system,'Segoe UI',sans-serif;
  --pad:clamp(16px,4vw,56px);
  --fit:calc(100vh - 250px); /* painting height: viewport less header, back link, cards */
}

*{box-sizing:border-box}
html,body{margin:0;padding:0}
body{
  background:var(--bg);color:var(--ink);
  font-family:var(--sans);font-weight:300;font-size:16px;line-height:1.6;
  -webkit-font-smoothing:antialiased;
}
img{display:block;max-width:100%}
a{color:inherit;text-decoration:none}
a:hover{color:var(--accent)}
button{font:inherit;color:inherit;background:none;border:0;padding:0;cursor:pointer}
:focus-visible{outline:2px solid var(--accent);outline-offset:3px}
.page{min-height:100vh;display:flex;flex-direction:column}
main{flex:1}
[hidden]{display:none!important}

.eyebrow{margin:0;font-size:12px;letter-spacing:.2em;text-transform:uppercase;color:var(--muted)}
.label{font-size:11px;letter-spacing:.14em;text-transform:uppercase;color:var(--muted)}
.poem{font-family:var(--serif);font-style:italic;color:var(--ink-soft);white-space:pre-line;margin:0}
.rule-link{font-size:13px;letter-spacing:.14em;text-transform:uppercase;border-bottom:1px solid var(--ink);padding-bottom:4px;display:inline-block}

/* ---------- header ---------- */
.site-header{
  position:sticky;top:0;z-index:20;
  background:color-mix(in srgb,var(--bg) 92%,transparent);
  backdrop-filter:blur(8px);
  border-bottom:1px solid var(--line);
  display:flex;align-items:center;justify-content:space-between;gap:24px;
  padding:14px var(--pad);
}
.site-header .logo img,.site-header .logo svg{height:46px;width:auto}
.nav{display:flex;align-items:center;gap:clamp(14px,2.5vw,32px);font-size:13px;letter-spacing:.12em;text-transform:uppercase}
.nav button{border-bottom:1px solid transparent;padding-bottom:3px}
.nav button[aria-current="true"]{border-bottom-color:var(--ink)}
.lang{display:flex;gap:6px;color:var(--faint)}

/* A small round link out to Instagram. Deliberately quiet: it sits beside the
   language toggle and should read as a footnote, not a call to action. 28px
   keeps it above the minimum target size without drawing the eye. */
.site-header .ig{
  display:inline-flex;align-items:center;justify-content:center;
  width:28px;height:28px;border-radius:50%;flex:0 0 auto;
  border:1px solid var(--line);color:var(--muted);
  transition:color 220ms ease,border-color 220ms ease;
}
.site-header .ig:hover{color:var(--accent);border-color:var(--accent)}
.site-header .ig svg{
  width:14px;height:14px;display:block;
  fill:none;stroke:currentColor;stroke-width:1.7;
  stroke-linecap:round;stroke-linejoin:round;
}
.site-header .ig svg .dot{fill:currentColor;stroke:none}
.lang button[aria-pressed="true"]{color:var(--ink)}

/* ---------- hero ---------- */
.hero{
  display:grid;grid-template-columns:repeat(auto-fit,minmax(min(330px,100%),1fr));
  gap:clamp(32px,5vw,72px);align-items:center;
  padding:clamp(40px,7vw,96px) var(--pad) clamp(40px,6vw,72px);
}
.hero-copy{max-width:460px}
.hero h1{
  margin:20px 0 0;font-family:var(--serif);font-weight:400;
  font-size:clamp(50px,8vw,96px);line-height:1.0;letter-spacing:-.01em;
}
.hero-poem{margin-top:clamp(28px,4vw,44px);padding-top:22px;border-top:1px solid var(--line)}
.hero-poem .poem{font-size:clamp(19px,2.1vw,25px);line-height:1.55}
.hero .see-works{margin-top:32px}

/* ---------- hero: type left, a quilt of her work bleeding off the right ----------
   The quilt is four columns of paintings butted together. Each column starts at a
   different height, which is what gives the outer edge its uneven, hand-hung line;
   the right side runs off the page rather than resolving into a rectangle. */
.hero-split{
  display:grid;grid-template-columns:minmax(320px,0.9fr) 1.1fr;
  gap:clamp(28px,4vw,64px);align-items:center;
  padding:clamp(26px,3.6vw,52px) 0 clamp(26px,3.6vw,52px) var(--pad);
  min-height:clamp(440px,64vh,660px);
}
.hero-split .hero-copy{max-width:460px}
.hero-mosaic{
  display:flex;gap:3px;height:100%;min-height:0;
  align-items:flex-start;overflow:hidden;
}
.mcol{display:flex;flex-direction:column;gap:3px;flex:1;min-width:0}
.hero-mosaic img{width:100%;height:auto;object-fit:cover;background:var(--panel)}
/* A hand-made collage keeps its own silhouette: full height, left-anchored, and
   whatever is wider than the column bleeds off the edge. */
.hero-mosaic .quilt-flat{width:100%;height:100%;background:none}
/* cover: a photographed hang fills the column, cropped as needed */
.hero-mosaic[data-collage-fit="cover"] .quilt-flat{object-fit:cover;object-position:center}
/* contain: a cut-out keeps its whole ragged silhouette, bleeding off the right */
.hero-mosaic[data-collage-fit="contain"] .quilt-flat{
  width:auto;max-width:none;object-fit:contain;object-position:left center;
}

/* Ragged: columns step down and up so neither edge is a straight line. */
.hero-split[data-edge="ragged"] .mcol[data-col="0"]{margin-top:7%}
.hero-split[data-edge="ragged"] .mcol[data-col="1"]{margin-top:0}
.hero-split[data-edge="ragged"] .mcol[data-col="2"]{margin-top:12%}
.hero-split[data-edge="ragged"] .mcol[data-col="3"]{margin-top:3%}
/* Flush: one clean block, if the ragged edge turns out to be too much. */
.hero-split[data-edge="flush"] .mcol{margin-top:0}
/* A flat collage carries its own edge, so the stagger must not apply. */
.hero-mosaic:has(.quilt-flat){align-items:stretch}

/* ---------- gallery ---------- */
.gallery{padding:0 var(--pad) clamp(56px,8vw,120px)}
.gallery-bar{
  display:flex;flex-wrap:wrap;align-items:baseline;justify-content:space-between;gap:16px;
  padding:22px 0;border-top:1px solid var(--line);border-bottom:1px solid var(--line);
  margin-bottom:clamp(28px,4vw,48px);
}
.gallery-bar .count{margin:0;font-size:13.5px;color:var(--muted)}

.rows{display:flex;flex-direction:column;gap:clamp(32px,5vw,80px)}
/* Each tile is as wide as its painting is wide, relative to its neighbours, so
   the row lands on one height with nothing cropped. --cap limits that height,
   which is what Short / Medium / Tall set. */
/* Rows fill the content width, so the left and right edges run straight down
   the page. Height then follows from how many pieces are in the row, which is
   an editorial choice rather than a side effect. --cap is only a ceiling, to
   stop a row of two wide canvases taking over the screen; most rows never
   reach it. */
.row{
  display:flex;align-items:flex-end;
  gap:clamp(18px,2.4vw,40px);
  --cap:clamp(300px,44vw,640px);
  max-width:calc(var(--cap) * var(--sum,3) + var(--gaps,0px));
  margin:0 auto;
}
.row[data-height="short"]{--cap:clamp(240px,30vw,440px)}
.row[data-height="tall"]{--cap:clamp(360px,56vw,820px)}

.tile{text-align:left;display:flex;flex-direction:column;min-width:0;animation:fade 500ms ease both}
.tile figure{margin:0;display:flex;flex-direction:column;width:100%}
/* A 2px rule holds the edge where a pale canvas meets the pale ground. Dark
   works carry their own edge and barely register it. */
.tile .frame{
  position:relative;display:block;width:100%;overflow:hidden;
  background:var(--panel);
  border:var(--frame-w) solid var(--frame);
}
.tile img{
  width:100%;height:100%;object-fit:cover;
  transition:transform 900ms cubic-bezier(.2,.6,.2,1);
}
/* "Show the whole photo" letterboxes against the page, not a grey panel —
   the painting should sit on the site's own ground. */
.tile[data-fit="contain"] img{object-fit:contain}
.tile[data-fit="contain"] .frame{background:var(--bg)}
/* No rule on a multi-panel piece. The composite already shows each panel as its
   own rectangle, so an outer border frames the photograph rather than the work. */
.tile[data-kind="diptych"] .frame,
.tile[data-kind="triptych"] .frame{border:0}
.tile:hover img{transform:scale(1.015)}
/* A tile with several ticked views slides between them: the views sit side by
   side on a track that shifts one frame-width at a time. */
.tile .frame.sliding{overflow:hidden}
.tile .frame .track{
  display:flex;height:100%;width:100%;
  transition:transform var(--tile-ease,520ms) cubic-bezier(.4,0,.2,1);
}
.tile .frame .track img{flex:0 0 100%;width:100%;height:100%}

/* Title and panel note sit on one line, ruled underneath — as in the draft. */
.tile figcaption{
  display:block;margin-top:14px;padding-bottom:12px;border-bottom:1px solid var(--line);
}
.tile .t{font-family:var(--serif);font-size:clamp(22px,2.2vw,28px);line-height:1.2}
@keyframes fade{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:none}}

.empty{padding:60px 0;color:var(--muted);font-size:14px}

/* ---------- work detail ---------- */
.work{padding:clamp(10px,1.4vw,18px) var(--pad) clamp(56px,8vw,110px)}
.back{font-size:12px;letter-spacing:.16em;text-transform:uppercase;color:var(--muted);margin-bottom:clamp(12px,1.6vw,20px)}
.work-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(340px,100%),1fr));gap:clamp(32px,4vw,72px);align-items:start}
/* The painting stays put while the details and poem beside it scroll. Both the
   stage and a lone image are sized to the viewport so the whole picture is in
   view at once — no scrolling needed to see the work itself. */
.work-images{display:flex;flex-direction:column;gap:12px;position:sticky;top:84px;align-self:start}
.work-images img{width:100%;background:var(--bg)}
.work-images .solo{
  width:auto;max-width:100%;height:var(--fit);
  margin:0 auto;object-fit:contain;
}
.work-images .note{margin:0;font-size:13px;color:var(--faint)}

/* ---------- filmstrip (works with more than one view) ----------
   The views drift sideways on their own — the whole piece, then each panel, or
   other angles. A click anywhere stops the drift and leaves the visitor to
   scroll it by hand. */
.strip{
  overflow-x:auto;overflow-y:hidden;cursor:pointer;
  scroll-snap-type:x mandatory;
  scrollbar-width:none;-ms-overflow-style:none;-webkit-overflow-scrolling:touch;
}
.strip::-webkit-scrollbar{display:none}
.strip-track{display:flex}
/* Each view takes the full width of the frame, so only one is ever in sight and
   the next one slides in from the right. */
.strip-slide{
  flex:0 0 100%;scroll-snap-align:start;
  height:var(--fit);background:var(--bg);
  display:flex;align-items:center;justify-content:center;
}
.strip-slide img{
  max-width:100%;height:100%;width:auto;
  object-fit:contain;user-select:none;
}
.strip.stopped{cursor:grab}
.strip-bar{
  display:flex;align-items:center;gap:14px;flex-wrap:wrap;
  font-size:13px;color:var(--faint);
}
/* Small cards to pick a view by hand. */
.shots{display:flex;gap:8px;flex-wrap:wrap}
.shots button{
  width:58px;border:1px solid transparent;background:var(--panel);
  opacity:.55;transition:opacity 250ms ease,border-color 250ms ease;
}
.shots button img{width:100%;height:58px;object-fit:cover}
.shots button:hover{opacity:.9}
.shots button[aria-current="true"]{opacity:1;border-color:var(--ink)}
.work-info{max-width:440px}
.work-info h1{margin:0;font-family:var(--serif);font-weight:400;font-size:clamp(38px,4.8vw,60px);line-height:1.04}
.specs{margin:clamp(20px,2.4vw,26px) 0 0;display:grid;grid-template-columns:auto 1fr;gap:8px 24px;font-size:14px;line-height:1.5}
.specs dt{padding-top:3px}
.specs dd{margin:0}
.commerce{margin-top:clamp(24px,3vw,32px);padding-top:clamp(18px,2.2vw,24px);border-top:1px solid var(--line)}
.prices{display:flex;gap:48px;flex-wrap:wrap;margin-bottom:14px}
.prices p{margin:0}
.prices .amount{font-family:var(--serif);font-size:26px}
.status-line{margin:0;font-size:15px;line-height:1.6;color:var(--ink-soft)}
.work-poem{margin:clamp(24px,3vw,34px) 0 0;padding-left:20px;border-left:1px solid var(--line)}
.work-poem .poem{font-size:clamp(19px,1.9vw,21px);line-height:1.55}

/* ---------- about ---------- */
.about{padding:clamp(40px,7vw,100px) var(--pad) clamp(56px,8vw,120px)}
.about-grid{max-width:1100px;margin:0 auto;display:grid;grid-template-columns:repeat(auto-fit,minmax(min(300px,100%),1fr));gap:clamp(36px,5vw,80px);align-items:start}
.about h1{margin:0 0 clamp(24px,3vw,40px);font-family:var(--serif);font-weight:400;font-size:clamp(42px,5.4vw,70px);line-height:1.02}
.about-body p{margin:0 0 18px;max-width:46ch;color:var(--ink-soft)}
.about-side{display:flex;flex-direction:column;gap:clamp(32px,4vw,56px)}
.about-poem{padding:clamp(28px,4vw,44px);background:var(--panel-soft)}
.about-poem .poem{font-size:clamp(21px,2.4vw,28px);line-height:1.65}

/* ---------- footer ---------- */
.site-footer{
  border-top:1px solid var(--line);padding:clamp(24px,3vw,40px) var(--pad);
  display:flex;flex-wrap:wrap;gap:16px;justify-content:space-between;
  font-size:12px;letter-spacing:.1em;color:var(--muted);
}
.site-footer .links{display:flex;flex-wrap:wrap;gap:24px}

/* ---------- responsive ---------- */
@media (max-width:820px){
  .work-images{position:static}
  /* Full column width on a phone. The width is definite here, so the
     aspect-ratio still reserves the right height before the file arrives. */
  .work-images .solo{height:auto}
  .strip-track img{height:min(52vh,380px)}
}
@media (max-width:900px){
  .hero-split{grid-template-columns:1fr;padding-right:0;min-height:0;gap:clamp(24px,5vw,40px)}
  .hero-mosaic{height:clamp(260px,46vw,400px)}
}
@media (max-width:700px){
  .row{flex-direction:column;align-items:stretch;gap:clamp(28px,7vw,40px);max-width:none}
  .row .tile{flex:1 1 auto!important}
  .hero-collage img:first-child{margin-top:0}
  .nav{gap:14px;font-size:12px}
  .rows{gap:clamp(28px,8vw,44px)}
}

/* ---------- draft preview ----------
   Only ever visible in the editor's preview tab. It exists because an
   unlabelled preview is indistinguishable from "my edits did nothing". */
.preview-bar{
  position:fixed;left:0;right:0;bottom:0;z-index:60;
  display:flex;align-items:center;justify-content:center;gap:18px;flex-wrap:wrap;
  background:var(--ink);color:var(--bg);
  padding:9px 16px;font-size:11px;letter-spacing:.16em;text-transform:uppercase;
}
.preview-bar button{
  border-bottom:1px solid var(--bg);padding-bottom:2px;
  font-size:11px;letter-spacing:.16em;text-transform:uppercase;
}
.preview-bar button:hover{color:#E7B9B9;border-bottom-color:#E7B9B9}

/* ---------- full-bleed hero (when a background image is set) ---------- */
.hero-full{
  display:flex;align-items:flex-end;padding:0;
  min-height:clamp(460px,72vh,700px);
  background-size:cover;
  background-position:var(--hero-focus,center);
  background-repeat:no-repeat;background-color:var(--panel);
  position:relative;
}
/* The painting is shown as itself. No darkening layer: these canvases are pale,
   and dimming one by half to carry white type ruins the thing you came to see.
   The words sit on a panel of the site's own ground instead. */
.hero-full .hero-overlay{
  position:relative;z-index:1;
  margin:var(--pad);
  max-width:min(520px,88%);
  background:color-mix(in srgb,var(--bg) 94%,transparent);
  backdrop-filter:blur(5px);
  padding:clamp(26px,3.2vw,40px) clamp(26px,3.2vw,42px) clamp(24px,3vw,36px);
  color:var(--ink);
}
.hero-full h1{
  margin:0;font-family:var(--serif);font-weight:400;
  font-size:clamp(40px,5.2vw,64px);line-height:1.02;letter-spacing:-.012em;color:var(--ink);
}
.hero-full .poem{
  margin:18px 0 0;font-size:clamp(17px,1.8vw,21px);line-height:1.5;color:var(--ink-soft);
}
.hero-full .see-works{margin-top:24px;color:var(--accent);border-bottom-color:var(--accent)}
.hero-full .see-works:hover{color:var(--accent-deep);border-bottom-color:var(--accent-deep)}

/* ===========================================================
   MOTION
   Transform and opacity only. Everything here is off under
   prefers-reduced-motion, and nothing moves the paintings
   themselves: a canvas that scales is a canvas misrepresented.
   =========================================================== */

/* 1 - rows arrive as rows. An IntersectionObserver adds .in; the
   per-tile --i staggers them left to right so a row reads as one
   hang rather than three unrelated objects. */
.tile{opacity:0;transform:translateY(14px)}
.tile.in{
  opacity:1;transform:none;
  transition:opacity 620ms cubic-bezier(.2,.6,.2,1) calc(var(--i,0) * 90ms),
             transform 620ms cubic-bezier(.2,.6,.2,1) calc(var(--i,0) * 90ms);
}

/* 2 - hover moves the frame, never the painting. The tile lifts and
   the caption rule draws in the accent; the image is untouched. */
.tile{transition:transform 420ms cubic-bezier(.2,.6,.2,1)}
.tile.in:hover{transform:translateY(-4px)}
.tile figcaption{position:relative}
.tile figcaption::after{
  content:"";position:absolute;left:0;right:0;bottom:-1px;height:1px;
  background:var(--accent);transform:scaleX(0);transform-origin:left;
  transition:transform 480ms cubic-bezier(.2,.6,.2,1);
}
.tile:hover figcaption::after,
.tile:focus-visible figcaption::after{transform:scaleX(1)}

/* 3 - the clicked tile expands into the work page instead of the page
   cutting. Paired by view-transition-name, set in JS for the one tile
   being opened. Browsers without the API simply navigate. */
@media (prefers-reduced-motion:no-preference){
  ::view-transition-old(art),::view-transition-new(art){
    animation-duration:420ms;
    animation-timing-function:cubic-bezier(.3,.7,.2,1);
  }
}

/* 4 - the poem sets itself, line by line, the one place on the site
   where the sequence carries meaning. */
.work-poem .line{
  display:block;opacity:0;transform:translateY(7px);
  animation:lineIn 620ms cubic-bezier(.2,.6,.2,1) forwards;
  animation-delay:calc(220ms + var(--i,0) * 180ms);
}
@keyframes lineIn{to{opacity:1;transform:none}}


@media (prefers-reduced-motion:reduce){
  .tile{opacity:1;transform:none;transition:none}
  .tile.in{transition:none}
  .tile.in:hover{transform:none}
  .tile figcaption::after{display:none}
  .work-poem .line{opacity:1;transform:none;animation:none}}

/* ---------- row alignment ----------
   A two-line title used to push its painting upward, because the row aligned
   the bottoms of whole tiles and a taller caption ate into the image's space.
   Subgrid puts every frame on one track and every caption on another, so the
   paintings line up no matter how long a title runs. */
@supports (grid-template-rows: subgrid){
  .row{
    display:grid;
    grid-template-columns:var(--cols);
    grid-template-rows:auto auto;
    align-items:end;
  }
  .row .tile{
    display:grid;
    grid-template-rows:subgrid;
    grid-row:span 2;
  }
  .row .tile figure{display:contents}

  /* This block sits after the phone breakpoint, so it has to collapse the row
     itself. The flex-direction:column up there means nothing once the row is a
     grid, which is how the gallery quietly went back to three across on a
     phone. Each tile still spans its own pair of tracks, so the frame and the
     caption stay in step. */
  @media (max-width:700px){
    .row{grid-template-columns:1fr;max-width:none}
  }
}

/* ---------- hero: a detail, enlarged ----------
   One painting zoomed past the point where it reads as a work, so the top of
   the page has an image that does not duplicate the gallery below it. The
   gradient carries the type instead of a box, and fades out before the most
   worked part of the crop. */
.hero.hero-detail{
  position:relative;display:block;overflow:hidden;
  min-height:clamp(430px,62vh,640px);
  padding:0;
  background-repeat:no-repeat;
  background-size:var(--hero-zoom,200%) auto;
  background-position:var(--hero-focus,70% 22%);
  background-color:var(--panel);
}
.hero-detail .hero-veil{
  position:absolute;inset:0;
  background:linear-gradient(90deg,
    color-mix(in srgb,var(--bg) 96%,transparent) 0%,
    color-mix(in srgb,var(--bg) 90%,transparent) 32%,
    color-mix(in srgb,var(--bg) 40%,transparent) 54%,
    transparent 68%);
}
.hero-detail .hero-copy{
  position:relative;z-index:1;
  max-width:min(520px,52%);
  padding:clamp(34px,5vw,64px) 0 clamp(34px,5vw,64px) var(--pad);
  display:flex;flex-direction:column;justify-content:center;
  min-height:clamp(430px,62vh,640px);
}
.hero-detail h1{
  margin:0;font-family:var(--serif);font-weight:400;
  font-size:clamp(44px,6.4vw,78px);line-height:1.02;letter-spacing:-.012em;
}
.hero-detail .poem{margin-top:22px;font-size:clamp(18px,1.9vw,22px);line-height:1.5}
.hero-detail .see-works{margin-top:28px;align-self:flex-start}

/* On a phone the crop sits above the words rather than behind them: type over
   a busy painting at that width is unreadable however soft the gradient. */
@media (max-width:760px){
  .hero.hero-detail{
    min-height:0;
    background-size:cover;background-position:center;
    display:flex;flex-direction:column;
  }
  .hero-detail::before{content:"";display:block;height:clamp(200px,42vw,300px)}
  .hero-detail .hero-veil{top:auto;height:auto;bottom:0;
    background:color-mix(in srgb,var(--bg) 97%,transparent)}
  .hero-detail .hero-copy{
    max-width:none;min-height:0;
    padding:clamp(24px,6vw,36px) var(--pad) clamp(28px,7vw,40px);
  }
}
