/* La Menuiserie de la Guill' - Lyon 7e
   Palette sampled by Lens from the real shopfront and workshop photographs:
   #E4411A facade sign lettering (dominant), #EDE8DC rendered limestone facade,
   #2D6080 window frames and door, #C8904A beech/pine, #D0CBC0 workshop plaster,
   #2D5233 green storage unit. Not derived from the trade. */

:root{
  --stone:#EDE8DC;        /* facade limestone: page background */
  --plaster:#D0CBC0;      /* workshop wall: slots, wells */
  --ink:#201E1A;
  --muted:#5A5347;        /* 6.2:1 on --stone */
  --brand:#E4411A;        /* the sign orange: large display only (3.4:1) */
  --brand-deep:#B8330F;   /* accessible orange: body links, buttons (4.9:1) */
  --blue:#2D6080;         /* the window frames */
  --wood:#C8904A;
  --green:#2D5233;
  --display:"Helvetica Neue",Arial,"Liberation Sans",system-ui,sans-serif;
  --body:system-ui,-apple-system,"Segoe UI",Roboto,"Liberation Sans",sans-serif;
  --serif:Georgia,"Times New Roman",serif;
  --wrap:60rem;
}

*,*::before,*::after{box-sizing:border-box}
html{-webkit-text-size-adjust:100%}
body{
  margin:0;background:var(--stone);color:var(--ink);
  font:1rem/1.6 var(--body);
  padding-bottom:5.5rem; /* clears the fixed call bar on phones */
}
img,svg{max-width:100%;height:auto}
a{color:var(--brand-deep)}
:focus-visible{outline:3px solid var(--blue);outline-offset:3px}
.wrap{max-width:var(--wrap);margin:0 auto;padding:0 1.25rem}
.sr{position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%)}

/* ---- the mark. The sign IS the identity: heavy caps, two lowercase i's,
   a dot at each end. Set in type rather than drawn, so it stays crisp. ---- */
.brand{display:inline-block;text-decoration:none;padding:.35rem 0}
.sign{
  display:block;font-family:var(--display);font-weight:900;
  text-transform:uppercase;letter-spacing:.03em;line-height:1;
  font-size:clamp(1.7rem,8.5vw,2.75rem);color:var(--brand);
}
.sign .i{text-transform:lowercase;font-weight:800}
.decal{
  display:block;font-family:var(--serif);font-style:italic;
  font-size:clamp(.85rem,3.6vw,1rem);color:var(--brand-deep);
  letter-spacing:.01em;margin-top:.2rem;
}

/* The page opens on the sign's orange rather than on stone. It is the one
   colour anybody recognises this workshop by, and it costs nothing to load. */
.head{
  border-top:10px solid var(--brand);
  border-bottom:3px solid var(--blue);
  background:var(--stone);
}
.head .wrap{padding-top:1rem;padding-bottom:.75rem}

/* ---- hero ----
   No photograph here, by operator instruction. Three CSS layers, nothing to
   download: a wash of the sign orange from the top right, vertical grain lines
   every 14px in the beech tone, limestone facade underneath. Worst measured
   contrast inside the wash: ink 10:1, muted 4.7:1. */
.hero{
  position:relative;isolation:isolate;overflow:hidden;
  padding:1.75rem 0 2rem;
  border-bottom:3px solid var(--blue);
  background:
    repeating-linear-gradient(90deg,
      rgba(200,144,74,.20) 0 1px,rgba(200,144,74,0) 1px 14px),
    radial-gradient(125% 105% at 100% 0%,
      rgba(228,65,26,.30) 0%,rgba(228,65,26,.14) 42%,rgba(228,65,26,.04) 70%,
      rgba(228,65,26,0) 88%),
    var(--stone);
}
/* Plank ends: four bars in the sign orange, the beech tone and the window
   blue, bled off the edge like boards stacked against a wall, filling the dead
   stone to the right of the text column on a wide screen. Drawn, not loaded. */
.hero::after{
  content:"";position:absolute;z-index:-1;display:none;
  top:-2rem;right:-1.5rem;width:19rem;height:calc(100% + 12rem);
  transform:rotate(-8deg);transform-origin:100% 0;
  background:
    linear-gradient(var(--brand),var(--brand)) no-repeat 0 0/2.1rem 100%,
    linear-gradient(var(--wood),var(--wood)) no-repeat 3.1rem 0/1.1rem 100%,
    linear-gradient(var(--brand),var(--brand)) no-repeat 5.2rem 0/.5rem 100%,
    linear-gradient(var(--blue),var(--blue)) no-repeat 6.7rem 0/.28rem 100%;
  opacity:.9;
}
/* The one solid block of the sign colour above the fold. Says what the trade
   is before the heading does, and gives the top of the page a hard edge. */
.eyebrow{
  display:inline-block;margin:0 0 .85rem;
  background:var(--brand-deep);color:#fff;   /* 5.9:1 */
  font:700 .76rem/1.25 var(--body);letter-spacing:.1em;text-transform:uppercase;
  padding:.45rem .7rem;
}
/* The neighbourhood name in the accessible orange, not the raw sign colour:
   #E4411A over the warmest part of the wash measures 1.9:1 on a phone. Colour
   rather than an underline, because the span wraps. */
.hl{color:var(--brand-deep)}
/* These two lines are deliberately quiet, so they are darkened here to keep a
   comfortable margin over the warmest part of the wash. */
.hero .caveat,.hero .fine{color:#3E3830}
.hero h1{
  font-family:var(--display);font-weight:900;text-transform:uppercase;
  letter-spacing:.01em;line-height:1.05;margin:0 0 .75rem;
  font-size:clamp(1.85rem,8.2vw,3rem);
}
.hero h1 sup{text-transform:lowercase;font-size:.55em;top:-.55em}
.lead{font-family:var(--serif);font-size:1.075rem;line-height:1.55;margin:0 0 1.1rem;max-width:34em}
/* No status dot on the hours. A green dot reads as a live "open now" light,
   and every hours source we have is a directory aggregator citing PagesJaunes,
   so that is a claim we cannot make. The caveat below carries the doubt. */
.hours{
  display:block;margin:0 0 .4rem;
  font-weight:600;font-size:.975rem;
}
/* The caveat is the only .caveat rule in this file. It sits directly under the
   hours in the hero and again in the horaires cell, marked with the same wood
   diamond in both, so the hours never read as settled fact anywhere. */
.caveat{
  display:block;margin:0 0 1.25rem;padding-left:1.3rem;position:relative;
  font-size:.85rem;line-height:1.45;color:var(--muted);max-width:32em;
}
.caveat::before{
  content:"";position:absolute;left:0;top:.4rem;
  width:.55rem;height:.55rem;background:var(--wood);transform:rotate(45deg);
}
.prac .caveat{margin:.4rem 0 0}
.fine{font-size:.875rem;color:var(--muted);margin:.9rem 0 0}
.rule{height:8px;border:0;margin:0;background:var(--brand)}
.grain{
  height:14px;
  background-image:repeating-linear-gradient(90deg,
    rgba(200,144,74,.55) 0 2px,rgba(200,144,74,0) 2px 6px,
    rgba(45,96,128,.18) 6px 7px,rgba(200,144,74,0) 7px 12px);
  background-color:var(--plaster);
}

/* ---- buttons: 48px minimum, real labels, never colour alone ---- */
.cta{display:flex;flex-wrap:wrap;gap:.75rem}
.btn{
  display:inline-flex;align-items:center;justify-content:center;
  min-height:48px;padding:.75rem 1.15rem;border-radius:2px;
  font:600 1rem/1.2 var(--body);text-decoration:none;text-align:center;
  cursor:pointer;transition:background-color .2s,color .2s;
}
.btn--p{background:var(--brand-deep);color:#fff;border:2px solid var(--brand-deep)}
.btn--p:hover{background:#93280B;border-color:#93280B}
.btn--s{background:transparent;color:var(--blue);border:2px solid var(--blue)}
.btn--s:hover{background:var(--blue);color:#fff}

/* ---- sections ---- */
section{padding:2rem 0}
.dh{
  font-family:var(--display);font-weight:900;text-transform:uppercase;
  letter-spacing:.06em;font-size:clamp(1.2rem,5.4vw,1.55rem);
  margin:0 0 1rem;
}
.dh::before,.dh::after{content:".";color:var(--brand)}
.band{background:#E5DFD1;border-top:3px solid var(--blue);border-bottom:3px solid var(--blue)}
.dark{background:var(--ink);color:var(--stone)}
.dark .dh{color:var(--stone)}
.dark a{color:var(--wood)}
/* the button must keep its own label colour: .dark a would otherwise win on
   specificity and leave wood text on deep orange, about 2:1 */
.dark .btn--p{color:#fff;border-color:var(--brand)}
p{margin:0 0 1rem}
.body-max{max-width:38em}

.facts{list-style:none;margin:1.25rem 0 0;padding:0;display:grid;gap:.5rem}
.facts li{padding-left:1.5rem;position:relative;font-size:.975rem}
.facts li::before{
  content:"";position:absolute;left:0;top:.55rem;
  width:.6rem;height:.6rem;background:var(--brand-deep);
}

/* ---- photographs: harvested from his own Google and Facebook pages, served
   from photos/; provenance in assets/manifest.json. The blue keyline echoes
   the real window frames. */
figure{margin:0}
figure img{display:block;width:100%;object-fit:cover}

/* ---- L'atelier: text left, photograph right on desktop; source order puts
   the text first, so a phone reads the words then sees the workshop.
   facebook-01 is 900x675, so 4/3 is native and nothing is cropped. */
.duo{display:grid;gap:1.5rem}
.duo__text>p:last-of-type{margin-bottom:0}
.duo__fig{border:3px solid var(--blue);background:var(--plaster)}
.duo__fig img{aspect-ratio:4/3}
.duo__fig figcaption{
  background:var(--blue);color:#fff;font-size:.82rem;line-height:1.4;
  padding:.5rem .75rem;
}

/* ---- work cards ---- */
.work{display:grid;gap:1.5rem;margin-top:.5rem;max-width:44rem}
.work h3{
  font-family:var(--display);font-weight:800;font-size:1.05rem;
  letter-spacing:.01em;margin:.85rem 0 .35rem;
}
.work p{font-size:.95rem;margin:0;color:#332F28}
.work figure{border:3px solid var(--blue);background:var(--plaster)}
/* Both pieces are 675x900 portraits: 4/5 takes six percent off the height and
   nothing else, and the 44rem cap stops two portraits towering on a wide
   screen. Do not "fix" their height with max-height, that crops them. */
.work figure img{aspect-ratio:4/5}

/* .hours and .caveat are both defined up in the hero block, marked with a wood
   diamond. Do not add a second .caveat rule here: a duplicate later in the file
   wins on source order and silently re-styles the hours caveat. */

/* ---- services ---- */
.svc{list-style:none;margin:0;padding:0;display:grid;gap:.6rem}
.svc li{
  border-left:4px solid var(--wood);padding:.45rem .75rem;
  background:rgba(255,255,255,.45);font-size:.975rem;
}
.svc li b{font-weight:700}

/* ---- practical ---- */
.prac{margin:0;display:grid;gap:1rem}
.prac dt{
  font:700 .78rem/1.2 var(--body);letter-spacing:.09em;text-transform:uppercase;
  color:var(--muted);margin-bottom:.25rem;
}
.prac dd{margin:0;font-size:.975rem}
/* 44px minimum on these: the email and Facebook links here were the undersized
   tap targets. inline-flex + min-height gives a real thumb-sized hit area
   without the link looking like a button. */
.prac a{
  font-weight:600;display:inline-flex;align-items:center;
  min-height:44px;padding:.25rem 0;
}
.foot a{display:inline-flex;align-items:center;min-height:44px;padding:.25rem 0}

/* ---- footer ---- */
.foot{background:var(--ink);color:var(--stone);padding:2rem 0 2.5rem;font-size:.875rem}
.foot .sign{font-size:1.5rem}
.foot p{margin:.4rem 0;color:#CFC9BC}
.foot a{color:var(--wood);font-weight:600}

/* ---- fixed call bar, phones only ---- */
.callbar{
  position:fixed;left:0;right:0;bottom:0;z-index:10;
  display:flex;gap:.6rem;padding:.6rem .75rem;
  background:rgba(237,232,220,.97);border-top:3px solid var(--blue);
}
.callbar .btn{flex:1 1 0;min-width:0;font-size:.975rem}

@media (min-width:700px){
  body{padding-bottom:0}
  .callbar{display:none}
  .head .wrap{display:flex;align-items:flex-end;justify-content:space-between;gap:1rem}
  /* With the photograph gone there is no frame that needs room to be legible,
     so the block is no taller than its own content plus air. */
  .hero{padding:3.5rem 0 4rem}
  .hero h1{max-width:14em}
  /* Keeps the text clear of the plank bars. The heading gets more room than
     the prose: at 34rem it broke after "LYON" and stranded the 7e. */
  .hero .wrap>*{max-width:min(100%,34rem)}
  .hero .wrap>h1{max-width:min(100%,42rem)}
  section{padding:3rem 0}
  /* text left, photograph right */
  .duo{grid-template-columns:1fr 1fr;gap:2.5rem;align-items:center}
  .work{grid-template-columns:1fr 1fr}
  .svc{grid-template-columns:1fr 1fr}
  .prac{grid-template-columns:1fr 1fr;gap:1.5rem}
  .hero .cta{gap:1rem}
}
@media (min-width:1000px){
  .work{gap:2rem 2.5rem}
  .duo{grid-template-columns:1.05fr .95fr;gap:3rem}
  .prac{grid-template-columns:repeat(4,1fr)}
}
/* The planks appear only once there is real dead space to their left: at
   820px the superscript e of "Lyon 7e" was touching the leading bar. */
@media (min-width:1150px){
  .hero::after{display:block}
}
@media (prefers-reduced-motion:reduce){
  *{transition:none!important;animation:none!important}
}
