/* Subset by subsetfonts.py to the characters this site renders.
   SIL Open Font License. Do not edit: rerun the script. */
@font-face{font-family:'Manrope';font-style:normal;font-weight:400 800;font-display:swap;src:url(/fonts/manrope-400.woff2) format('woff2')}

.skip{position:absolute;left:-9999px;top:0;z-index:300;background:var(--ink);color:#fff;
  padding:12px 18px;border-radius:0 0 10px 0;font-size:0.875rem;font-weight:600;text-decoration:none}
.skip:focus{left:0}
:focus-visible{outline:2px solid var(--accent);outline-offset:3px;border-radius:3px}

/* Type is sized in rem so it follows the reader's browser font-size preference.
   Everything else (padding, gaps, borders, the map) stays in px: only the text
   should grow when someone sets a larger default, not the whole layout. */
:root{
  /* This site is white on purpose, and saying so is what keeps it white. Chrome on
     Android auto-darkens pages that declare no colour scheme: it would invert the
     paper the photographs are printed on, on the platform most people arrive from.
     It also stops the scrollbars and any form control rendering dark against it.
     Light rather than "light dark": there is no dark palette here to switch to. */
  color-scheme: light;
  --bg:#FFFFFF; --soft:#FAFAF9; --ink:#111113; --ink2:#5B5B63; --ink3:#73737B;
  --line:#EBEBEE; --line2:#DCDCE1; --accent:#CF422A; --r:14px;
}
*{margin:0;padding:0;box-sizing:border-box}
/* Safari on iOS inflates body text when a page is turned to landscape, which is a
   help on a desktop layout squeezed onto a phone and a hindrance on one already
   built for it: the type this site sets carefully would resize itself. */
html{scroll-behavior:smooth;-webkit-text-size-adjust:100%;text-size-adjust:100%}
body{background:var(--bg);color:var(--ink);font-family:"Manrope",sans-serif;font-size:1rem;
  /* 100vh on iOS is the height with the toolbars HIDDEN, so a sticky-footer floor of
     100vh makes every page taller than the screen actually is: the short ones, like
     contact, pick up a scroll with nothing to scroll to. dvh is the height right now.
     Both are written: a browser that does not know dvh keeps the old behaviour. */
  min-height:100vh;min-height:100dvh;display:flex;flex-direction:column;
  line-height:1.6;-webkit-font-smoothing:antialiased}
img{display:block;max-width:100%}
a{color:inherit}
.wrap{max-width:1180px;margin:0 auto;padding:0 28px}
/* Japanese inside an English or French page. Only `.jp` reached for the real
   face, so the language switcher's 日本語 and Japanese book titles fell through
   to whatever the operating system had — Hiragino here, Yu Gothic on Windows,
   tofu on a machine with no CJK font — while the site was already shipping
   those exact glyphs. Placed before .jp so that rule still wins where it
   applies, and harmless on the Japanese pages, where body says the same. */
:lang(ja){font-family:"Manrope","Zen Kaku Gothic New",sans-serif}
.jp{font-family:"Zen Kaku Gothic New",sans-serif;font-weight:400}
/* Japanese breaks a line between any two characters, so a katakana loanword can be
   cut in half. Ordinary in body text; in a 50px headline it reads as a fault. The
   build wraps katakana runs in headings only, and only short ones. */
.nb{white-space:nowrap}
.eyebrow{font-size:0.75rem;font-weight:600;letter-spacing:.09em;text-transform:uppercase;color:var(--ink3)}

/* ---------- nav / footer ---------- */
header.nav{position:sticky;top:0;z-index:60;background:rgba(255,255,255,.88);
  backdrop-filter:blur(14px);border-bottom:1px solid var(--line)}
header.nav .wrap{display:flex;align-items:center;justify-content:space-between;height:64px;gap:20px}
.brand{font-weight:800;font-size:1.0312rem;letter-spacing:-.02em;text-decoration:none}
.brand span{color:var(--accent)}
nav.links{display:flex;gap:26px}
nav.links a{font-size:0.9062rem;font-weight:500;color:var(--ink2);text-decoration:none;transition:color .18s}
nav.links a:hover{color:var(--ink)}
.langs{display:flex;gap:2px;background:var(--soft);border:1px solid var(--line);border-radius:999px;padding:3px}
.langs a{font-size:0.7812rem;font-weight:600;color:var(--ink3);text-decoration:none;padding:4px 11px;
  border-radius:999px;transition:background .18s,color .18s}
.langs a.on{background:var(--ink);color:#fff}
footer{padding:34px 0 46px;border-top:1px solid var(--line);margin-top:10px}
footer .wrap{display:flex;justify-content:space-between;gap:18px;flex-wrap:wrap;
  font-size:0.8438rem;color:var(--ink3)}
/* Vertical padding on an inline element overflows its line box without moving
   anything on screen, so 19px of text becomes a 39px tap target. Only vertical: the
   five sit on one row separated by "·", and horizontal padding would overlap them
   into each other. Nothing interactive sits above or below, so nothing collides. */
footer a{text-decoration:none;padding:10px 0}
footer a:hover{color:var(--ink)}

/* ---------- shared blocks ---------- */
section{padding:74px 0;border-bottom:1px solid var(--line)}
/* The footer draws its own top rule, so the last section's was always a second line:
   10px above it on a long page, and on contact and 404 — short enough that the flex
   spacer pushes the footer down — a rule stranded 300px above it, separating nothing
   from nothing. Every section is a direct child of main, so this cannot reach one
   that is genuinely mid-page. */
main > section:last-of-type{border-bottom:0}
section.alt{background:var(--soft)}
.head{max-width:62ch;margin-bottom:34px}
.head h1,.head h2{font-size:clamp(1.625rem,3.1vw,2.25rem);font-weight:800;letter-spacing:-.032em;margin:9px 0 11px}
.head h1 .jp{font-size:.62em;font-weight:500;color:var(--ink3);margin-left:9px;letter-spacing:0}
.head .sub{font-size:1.0312rem;color:var(--ink2)}
.crumb{font-size:0.8438rem;color:var(--ink3);margin-bottom:26px}
.crumb a{text-decoration:none;font-weight:600;color:var(--ink2)}
.crumb a:hover{color:var(--accent)}
/* The separator was opacity:.5, which took it to 1.96:1 on 55 pages. No opacity
   below 1 keeps --ink3 legible, so the margin does the separating instead: the
   links are already darker and heavier than the slash between them. */
.crumb span{margin:0 7px}
.more{margin-top:26px}
.more a{font-size:0.9375rem;font-weight:600;text-decoration:none;border-bottom:1.5px solid var(--accent);padding-bottom:2px}

/* ---------- hero ---------- */
.hero{padding:76px 0 50px}
.hero .split{display:grid;grid-template-columns:1fr 1fr;gap:56px;align-items:center}
.hero h1{font-size:clamp(2.125rem,4.3vw,3.125rem);font-weight:800;letter-spacing:-.035em;line-height:1.1;margin:16px 0 20px}
.hero h1 em{font-style:normal;color:var(--accent)}
.hero .lede{font-size:1.0625rem;color:var(--ink2);line-height:1.68;max-width:50ch}
.hero .lede + .lede{margin-top:14px}
.hero .lede strong{color:var(--ink);font-weight:600}
.hero .lede a{color:var(--ink);font-weight:600;text-decoration:none;border-bottom:1.5px solid var(--accent)}
.cta{display:flex;gap:11px;flex-wrap:wrap;margin-top:28px}
.cta a{display:inline-flex;align-items:center;gap:8px;padding:12px 21px;border-radius:999px;
  font-size:0.9062rem;font-weight:600;text-decoration:none;transition:transform .18s,border-color .18s}
.cta a.p{background:var(--ink);color:#fff}
.cta a.g{border:1px solid var(--line2)}
.cta a:hover{transform:translateY(-1px)}
.mosaic{display:grid;grid-template-columns:repeat(3,1fr);grid-auto-rows:112px;gap:10px}
.mosaic .tile{overflow:hidden;border-radius:10px;background:var(--soft);display:block;cursor:zoom-in;margin:0}
.mosaic .tile:nth-child(1){grid-row:span 2;grid-column:span 2}
.mosaic .tile:nth-child(2){grid-row:span 2}
.mosaic .tile:nth-child(5){grid-row:span 2}
.mosaic img{width:100%;height:100%;object-fit:cover;transition:transform .7s cubic-bezier(.2,.8,.2,1)}
.mosaic .tile:hover img{transform:scale(1.05)}

/* ---------- series cards ---------- */
.wayh2{font-size:1.75rem;font-weight:700;letter-spacing:-.025em;margin:0 0 26px}
@media(max-width:900px){.wayh2{font-size:1.5rem}}
/* Wide tracking on a small uppercase label is a Latin idiom: uppercase does nothing
   to kana or kanji, and the extra space just makes Japanese look loose. Tighten the
   labels on the Japanese pages; the map and region headings keep a little, since they
   sit above a list and need the separation. */

/* Headings were breaking with a single word on the last line ("Some of what I've
   kept since / 2010."). balance evens the lines out; pretty keeps a paragraph from
   ending on a widow. Both are ignored by browsers that do not know them. */
h1,h2,h3,.chaplead,.lede,.sub,.stand,.chapnum+h2{text-wrap:balance}
p,li{text-wrap:pretty}
/* Japanese forbids certain characters from opening or closing a line; strict applies
   the full rule set rather than the relaxed default.

   strict says where a line may NOT break. It does not say where it should, and Japanese
   sets without spaces, so the default is to break between any two characters. The home
   page read "日本に住んでいま / す。", "廃 / 墟" — the site's own subject, cut in half —
   and "スタジオ Meow Arts / でWordPress", which strands the particle from the noun it
   belongs to. auto-phrase breaks on phrase boundaries instead: measured on that same
   paragraph, every clause now ends where it should and 廃墟 stays whole. A browser that
   does not know the value ignores it and gets exactly what it gets today. */
:lang(ja){line-break:strict;word-break:auto-phrase}

/* a quiet line at the foot of the prefecture and season pages: these are where a
   picture editor lands, and licensing was declared only in the structured data */
/* On /photographs/ the licensing line is the whole of the last section, so its own
   rule landed a hundred pixels below the section rule above it with nothing in
   between. One rule: the section boundary, then the line. */
@media screen{
  .uselast{padding:34px 0 0}
  /* scoped to screen: unscoped, this outranks the print rule for .use and the
     printed line would lose its rule, which check 33 refused */
  .uselast .use{margin:0;padding-top:0;border-top:0}
}
.use{margin:34px 0 0;padding-top:18px;border-top:1px solid var(--line);
  font-size:0.9375rem;color:var(--ink2)}
.use a{color:var(--ink);font-weight:600;text-decoration:none;
  border-bottom:1px solid var(--line2);padding-bottom:1px;transition:border-color .2s}
.use a:hover{border-color:var(--ink)}
/* --- /photographs/ as a route ---------------------------------------------- */
.opengrid{display:grid;grid-template-columns:minmax(0,5fr) minmax(0,5fr);
  gap:56px;align-items:center}
.open .ways{margin:26px 0 0;padding-top:22px;border-top:1px solid var(--line);
  font-size:0.8125rem;letter-spacing:.14em;text-transform:uppercase;color:var(--ink3)}
.openhero .tile{display:block;margin:0;border-radius:14px;overflow:hidden;
  aspect-ratio:4/3;background:var(--soft)}
.openhero img{width:100%;height:100%;object-fit:cover;display:block;
  transition:transform .6s cubic-bezier(.2,.8,.2,1)}
.openhero .tile:hover img{transform:scale(1.03)}
@media(max-width:900px){
  .opengrid{grid-template-columns:1fr;gap:30px}
  .openhero .tile{aspect-ratio:16/9}
}
.chapter{padding:78px 0}
.chapter+.chapter{border-top:1px solid var(--line)}
.chap{display:grid;grid-template-columns:minmax(0,4fr) minmax(0,6fr);
  gap:56px;align-items:center}
.chapter.flip .chaptext{order:2}
@media(min-width:901px){
  .chapter.flip .chap{grid-template-columns:minmax(0,6fr) minmax(0,4fr)}}
.chapnum{font-size:0.8125rem;font-weight:700;letter-spacing:.18em;color:var(--ink3);
  margin:0 0 14px}
.chaptext h2{font-size:2.125rem;font-weight:700;letter-spacing:-.03em;margin:0 0 10px}
.chaplead{font-size:1.1875rem;font-weight:600;margin:0 0 12px}
.chapblurb{font-size:1rem;color:var(--ink2);margin:0 0 22px;max-width:44ch}
.chaplink{font-size:0.9375rem;font-weight:600;text-decoration:none;color:var(--ink);
  border-bottom:1px solid var(--line2);padding-bottom:2px;transition:border-color .2s}
.chaplink:hover{border-color:var(--ink)}
/* one tall frame, two stacked beside it */
.chapshots{display:grid;grid-template-columns:1fr 1fr;gap:12px}
.chapshots .tile:not(:first-child){aspect-ratio:3/2}
.chapshots .tile{margin:0;overflow:hidden;border-radius:12px;background:var(--soft);
  display:block;position:relative}
.chapshots .tile:first-child{grid-row:span 2}
/* A series with no portrait in it cannot fill a two-row slot, and forcing one there
   cost half the photograph. France is 25 landscape frames and not one vertical. */
.chapshots.flat .tile:first-child{grid-row:auto;grid-column:span 2;aspect-ratio:16/9}
.chapshots .tile img{width:100%;height:100%;object-fit:cover;display:block;
  transition:transform .6s cubic-bezier(.2,.8,.2,1)}
.chapshots .tile:hover img{transform:scale(1.04)}

/* the prefecture map, sitting inside the Japan chapter */
.mapin{margin-top:64px;padding-top:44px;border-top:1px solid var(--line)}
.maph{font-size:1.375rem;font-weight:700;letter-spacing:-.02em;margin:0 0 26px}

/* the four seasons, as one strip you read left to right */
.sinter h2{font-size:2.125rem;font-weight:700;letter-spacing:-.03em;margin:0 0 8px}
.sstrip{display:grid;grid-template-columns:repeat(4,1fr);gap:14px;margin-top:28px}
.sstrip a{position:relative;display:block;border-radius:12px;overflow:hidden;
  aspect-ratio:3/4;background:var(--soft);text-decoration:none}
.sstrip img{width:100%;height:100%;object-fit:cover;display:block;
  transition:transform .6s cubic-bezier(.2,.8,.2,1)}
.sstrip a:hover img{transform:scale(1.05)}
.sstrip span{position:absolute;left:0;right:0;bottom:0;padding:34px 14px 13px;
  color:#fff;font-weight:700;font-size:1.0625rem;letter-spacing:-.01em;
  background:linear-gradient(to top,rgba(0,0,0,.78),rgba(0,0,0,.28) 55%,rgba(0,0,0,0));
  text-shadow:0 1px 3px rgba(0,0,0,.55)}

@media(max-width:900px){
  .chapter{padding:52px 0}
  .chap{grid-template-columns:1fr;gap:28px}
  .chapter.flip .chaptext{order:0}
  .chaptext h2{font-size:1.75rem}
  /* 3/4, not 16/9: this slot is filled with a portrait photograph chosen to fit the
     two-row shape it has on a wide screen, and a 16/9 band cut more than half of it
     away. Full width and taller than wide is what that frame is for. */
  .chapshots .tile:first-child{grid-row:auto;grid-column:span 2;aspect-ratio:3/4}
  .sinter h2{font-size:1.75rem}
}
/* A deliberate two-line heading reads well wide, but on a phone the forced break
   lands mid-thought and the rest wraps again underneath it. Below this width the
   break comes out and text-wrap:balance decides. */
@media(max-width:640px){h1 br{display:none}}

@media(max-width:640px){
  .sstrip{grid-template-columns:1fr 1fr;gap:10px}
  .mapin{margin-top:40px;padding-top:32px}
}

/* --- the three ways into the photographs ---------------------------------- */
.ways{font-size:0.8125rem;letter-spacing:.14em;text-transform:uppercase;
  color:var(--ink3);margin:0 0 34px}
.waysub{font-size:1rem;color:var(--ink2);max-width:56ch;margin:0 0 26px}

/* the four seasons, as tabs on a season page */
.seasonnav{display:flex;flex-wrap:wrap;gap:8px;margin:0 0 30px}
.seasonnav a{font-size:0.875rem;padding:7px 15px;border-radius:999px;
  border:1px solid var(--line);color:var(--ink2);text-decoration:none;
  transition:border-color .2s,color .2s,background .2s}
.seasonnav a:hover{border-color:var(--ink3);color:var(--ink)}
.seasonnav a.on{background:var(--ink);border-color:var(--ink);color:#fff}

.scards{display:grid;grid-template-columns:repeat(4,1fr);gap:16px}
@media(min-width:1001px){.scards.three{grid-template-columns:repeat(3,1fr)}}
.scard{text-decoration:none;display:block}
.scard .im{overflow:hidden;border-radius:12px;aspect-ratio:4/3;background:var(--soft)}
.scard img{width:100%;height:100%;object-fit:cover;transition:transform .6s cubic-bezier(.2,.8,.2,1)}
.scard:hover img{transform:scale(1.04)}
.scard .meta{display:flex;align-items:baseline;justify-content:space-between;gap:10px;margin:13px 0 4px}
.scard h3{font-size:1.125rem;font-weight:700;letter-spacing:-.02em}
.scard .jp{font-size:0.8438rem;color:var(--ink3);margin-left:5px}
.scard p{font-size:0.875rem;color:var(--ink2)}

/* ---------- photo grid ---------- */
.grid{columns:4;column-gap:10px}
.grid.few{columns:2;max-width:760px}
.grid.some{columns:3;max-width:1000px}
.grid .tile{break-inside:avoid;margin:0 0 10px;display:block;overflow:hidden;border-radius:10px;
  background:var(--soft);cursor:zoom-in;position:relative}
.grid img{width:100%;height:auto;transition:transform .6s cubic-bezier(.2,.8,.2,1)}
.grid .tile:hover img{transform:scale(1.04)}
.clinks{display:grid;grid-template-columns:repeat(3,1fr);gap:12px;max-width:840px}
.clinks a{border:1px solid var(--line);border-radius:12px;padding:20px 22px;text-decoration:none;
  transition:border-color .18s,transform .18s}
.clinks a:hover{border-color:var(--ink);transform:translateY(-2px)}
.clinks b{display:block;font-size:1rem;font-weight:700;margin-bottom:3px}
.clinks span{font-size:0.8438rem;color:var(--ink3)}

/* ---------- prose ---------- */
.prose{max-width:672px;margin:0 auto;padding:0 28px}
.prose p{font-size:1.0938rem;line-height:1.78;color:#3A3A40;margin-bottom:20px}
.prose .first{font-size:1.1875rem;color:#2A2A30}
.prose .first::first-letter{float:left;font-size:4rem;line-height:.82;font-weight:800;
  margin:5px 11px 0 0;color:var(--accent)}

/* ---------- biography page ---------- */
.bio-hero{padding:82px 0 54px;text-align:center}
.bio-hero h1{font-size:clamp(2.125rem,4.8vw,3.625rem);font-weight:800;letter-spacing:-.038em;
  line-height:1.06;margin:14px 0 22px}
.bio-hero .stand{font-size:1.1875rem;color:var(--ink2);max-width:46ch;margin:0 auto}
.bleed{max-width:1320px;margin:0 auto 54px;padding:0 28px}
.bleed img{width:100%;aspect-ratio:21/9;object-fit:cover;border-radius:16px}
.duo{max-width:1320px;margin:54px auto;padding:0 28px;display:grid;grid-template-columns:1fr 1fr;gap:16px}
.duo img{width:100%;aspect-ratio:4/3;object-fit:cover;border-radius:14px}
blockquote{max-width:760px;margin:54px auto;padding:0 28px;text-align:center;
  font-size:clamp(1.3125rem,2.6vw,1.8125rem);font-weight:700;letter-spacing:-.025em;line-height:1.35}
/* auto-fit, not repeat(3,1fr): the prints page carries two of these and the fixed
   three columns left a third of the row empty beside them. Same shape as the series
   cards, which were widened for the same reason. */
.endlinks{display:grid;grid-template-columns:repeat(3,1fr);gap:12px;margin:64px auto 0;
  padding-top:44px;border-top:1px solid var(--line)}
/* The prints page carries two of these, and three fixed columns left a third of the
   row empty beside them. Scoped to the width where three columns are the default,
   because specificity ignores media queries: unscoped, `.endlinks.two` outranks the
   plain `.endlinks` inside the max-width query and would hold two columns on a phone. */
@media(min-width:1001px){.endlinks.two{grid-template-columns:repeat(2,1fr)}}
.el{border:1px solid var(--line);border-radius:12px;padding:22px 24px;text-decoration:none;
  transition:border-color .18s,transform .18s}
.el:hover{border-color:var(--ink);transform:translateY(-2px)}
.el b{display:block;font-size:1.0312rem;font-weight:700;margin-bottom:4px}
.el span{font-size:0.8438rem;color:var(--ink3)}
.page-bio footer{margin-top:70px}

@media(max-width:1000px){
  .hero .split{grid-template-columns:1fr;gap:38px}
  .scards{grid-template-columns:1fr 1fr}
  .grid{columns:2}
  .grid.few,.grid.some{columns:2;max-width:none}
  .duo,.endlinks,.clinks{grid-template-columns:1fr}
  /* The nav used to be display:none below this width, which left every phone with
     no way to reach any page but the homepage. It becomes a scrollable strip on its
     own row instead: real links, no JavaScript, no hamburger to discover. */
  header.nav .wrap{flex-wrap:wrap;height:auto;padding-top:11px;padding-bottom:0}
  /* The header is 64px on a wide screen and 124px here, because the links move to
     their own row. .stop clears 96px, which was measured against the 64px one, so
     arriving at a #stop from one of the old /blog/ URLs left the heading 14px below
     the header instead of 32px. Same air, both layouts. */
  .stop{scroll-margin-top:156px}
  /* The padding sits on the links, not on the strip: same height on screen, but each
     label is a 44px-tall target instead of a 22px one. A phone nav made of 22px taps
     is the one thing on this page everybody has to use. */
  /* At 390px the strip is 43px too narrow for five labels, so Contact sits 17px past
     the right edge — and the scrollbar is hidden, so nothing at all said it scrolls.
     A soft right edge does, and it is the only affordance a horizontal scroller gets
     on a touch screen. Measured, not guessed: Contact's right edge is at 405. */
  nav.links{order:3;width:100%;gap:20px;margin-top:11px;padding:0;
    overflow-x:auto;scrollbar-width:none;-webkit-overflow-scrolling:touch;
    border-top:1px solid var(--line);
    -webkit-mask-image:linear-gradient(90deg,#000 calc(100% - 26px),transparent);
    mask-image:linear-gradient(90deg,#000 calc(100% - 26px),transparent)}
  nav.links::-webkit-scrollbar{display:none}
  /* The strip holds ~385px of links in ~335px and its scrollbar is hidden, so the
     last item was simply cut off with nothing to say it could be scrolled. Fading
     the right edge is the cue. Trying to make five labels fit instead is not an
     option: the French ones (Photographies, Biographie, Logiciels) are longer. */
  nav.links{-webkit-mask-image:linear-gradient(to right,#000 calc(100% - 30px),transparent);
    mask-image:linear-gradient(to right,#000 calc(100% - 30px),transparent)}
  nav.links a{white-space:nowrap;font-size:0.875rem;padding:11px 0}
}
@media(max-width:640px){
  .regcol{grid-template-columns:1fr}
  .reglist a{font-size:0.8125rem;padding:5px 10px}
  .scards{grid-template-columns:1fr;grid-column:auto}
  .grid{columns:2;column-gap:8px}
  .grid .tile{margin-bottom:8px}
  .prefhead{gap:18px}
  .prefmap{max-width:190px}
  .bio-hero{padding:52px 0 34px}
  .prose{padding:0 24px}
  .wrap{padding:0 20px}
}

/* ---------- Japanese typography ---------- */
.lang-ja{font-family:"Manrope","Zen Kaku Gothic New",sans-serif}
.lang-ja h1,.lang-ja h2,.lang-ja h3,.lang-ja .brand{font-family:"Zen Kaku Gothic New",sans-serif;
  letter-spacing:-.01em;font-weight:700}
.lang-ja .prose p,.lang-ja .hero .lede,.lang-ja .head .sub{line-height:1.95;letter-spacing:.01em}
.lang-ja .prose .first::first-letter{float:none;font-size:inherit;margin:0;color:inherit}

/* biography: a three-up interlude alongside the existing two-up */
.trio{max-width:1320px;margin:54px auto;padding:0 28px;display:grid;
  grid-template-columns:repeat(3,1fr);gap:14px}
.trio img{width:100%;aspect-ratio:3/2;object-fit:cover;border-radius:12px}
@media(max-width:900px){.trio{grid-template-columns:1fr;gap:12px}}

/* ---------- software ---------- */
.swhero{padding:74px 0 46px;border-bottom:1px solid var(--line)}
.swbig{display:flex;align-items:baseline;gap:14px;margin-top:6px;text-decoration:none;
  border:1px solid var(--line);border-radius:14px;padding:22px 26px;width:fit-content;
  transition:border-color .2s,transform .2s}
.swbig:hover{border-color:var(--ink);transform:translateY(-2px)}
.swbig b{font-size:1.625rem;font-weight:800;letter-spacing:-.03em}
.swbig span{font-size:0.8438rem;font-weight:600;color:var(--ink3)}
.sw{padding:60px 0;border-bottom:1px solid var(--line)}
.sw:nth-of-type(even){background:var(--soft)}
.swgrid{display:grid;grid-template-columns:300px 1fr;gap:56px;align-items:start}
/* A group's own mark. Illustrations, not strokes, so they get room the 24px line
   icons did not need, and they sit on the same baseline as those. */
/* One rule, sized by the context it lands in. Written as .swt .swlogo, the teaser
   pair went dead the moment the row fell back to line icons, and would have needed
   re-adding at exactly the size nobody would remember. A custom property on .swt
   survives both states: the card is always there, the mark is not. */
.swlogo{display:block;margin-bottom:10px}
.swlogo img{width:var(--mark,52px);height:var(--mark,52px);object-fit:contain}
.swhead{position:sticky;top:88px}
.swhead h2{font-size:1.5rem;font-weight:800;letter-spacing:-.03em;margin-bottom:10px}
.swhead p{font-size:0.9062rem;color:var(--ink2);line-height:1.7}
.swlist{list-style:none;display:grid;gap:0;border-top:1px solid var(--line)}
.swlist li{display:block}
.swlist li b{font-size:1.0312rem;font-weight:700;letter-spacing:-.02em}
.swlist li span{font-size:0.9062rem;color:var(--ink2);line-height:1.65}
.swteaser{display:grid;grid-template-columns:repeat(4,1fr);gap:12px}
.swt{--mark:34px;
  border:1px solid var(--line);border-radius:14px;padding:22px 24px;text-decoration:none;
  display:flex;flex-direction:column;gap:14px;transition:border-color .2s,transform .2s}
.swt:hover{border-color:var(--ink);transform:translateY(-2px)}
.swt .ico{width:24px;height:24px;color:var(--accent);
  margin:5px 0}                       /* 24 + 10 = the 34px a mark occupies */
.swt b{font-size:1rem;font-weight:700;letter-spacing:-.02em}
/* the gap is set for icon-then-label; the names sit tight under the label */
.swt b{margin-bottom:-8px}
.swt span{font-size:0.8438rem;color:var(--ink2);line-height:1.5}
@media(max-width:900px){
  .swgrid{grid-template-columns:1fr;gap:24px}.swhead{position:static}
  .swlist li{grid-template-columns:1fr;gap:4px}
  .swteaser{grid-template-columns:1fr 1fr}
}
.page-books .head,.page-sw .head{margin-bottom:30px}

/* country chip — Elsewhere only; country is the finest location ever published.
   The chip was scoped to .grid, so the three World frames in the story emitted it
   and then had it clipped by the tile's overflow:hidden — invisible, for months. */
.grid .tile,.chapshots .tile{position:relative}
.tile .cc{position:absolute;left:10px;bottom:10px;font-size:0.7188rem;font-weight:600;
  letter-spacing:.03em;color:#fff;background:rgba(17,17,19,.72);backdrop-filter:blur(6px);
  border-radius:999px;padding:4px 10px;pointer-events:none}
/* In the long grid the chip waits for hover so the pictures stay clean. On a touch
   screen hover never happens, so there it simply stays — otherwise the only place
   name the site publishes would be unreachable on a phone. */
@media (hover:hover){
  .grid .tile .cc{opacity:0;transform:translateY(4px);transition:opacity .2s,transform .2s}
  .grid .tile:hover .cc{opacity:1;transform:translateY(0)}
}

/* ---------- lightbox: the photograph, nothing else ---------- */
#lb{position:fixed;inset:0;z-index:200;background:rgba(255,255,255,.975);
  backdrop-filter:blur(10px);display:flex;align-items:center;justify-content:center;padding:48px}
#lb[hidden]{display:none}
#lb img{max-width:92vw;max-height:86vh;width:auto;height:auto;border-radius:6px;
  box-shadow:0 30px 80px -40px rgba(0,0,0,.55)}
#lb button{position:absolute;display:grid;place-items:center;cursor:pointer;
  border:1px solid var(--line2);background:#fff;color:var(--ink2);border-radius:50%;
  font-size:1.0625rem;line-height:1;transition:border-color .18s,color .18s,transform .18s}
#lb button:hover{border-color:var(--ink);color:var(--ink)}
#lb .x{top:22px;right:26px;width:40px;height:40px;font-size:0.875rem}
#lb .prev,#lb .next{top:50%;transform:translateY(-50%);width:46px;height:46px}
#lb .prev{left:26px}#lb .next{right:26px}
#lb .prev:hover,#lb .next:hover{transform:translateY(-50%) scale(1.06)}
#lb .n{position:absolute;bottom:24px;left:50%;transform:translateX(-50%);
  font-size:0.7812rem;color:var(--ink3);font-variant-numeric:tabular-nums}
@media(max-width:640px){
  #lb{padding:16px}#lb .prev{left:8px}#lb .next{right:8px}
  #lb .prev,#lb .next{width:40px;height:40px}
}
.jmap{width:100%;height:auto;display:block}
.jmap .pf path{fill:#DEDEDA;stroke:#fff;stroke-width:1.4;stroke-linejoin:round;
  transition:fill .15s}
.jmap a.pf{cursor:pointer}
.jmap a.pf:hover path{fill:var(--accent)}
.jmap .pf.on path{fill:var(--accent)}
.jmap .inset{fill:none;stroke:var(--line2);stroke-width:1.5;stroke-dasharray:4 4}
.jmap .insetlab{font-family:Manrope,sans-serif;font-size:0.9375rem;fill:var(--ink3)}

/* map + region lists, side by side, on /photographs/ */
.mapgrid{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:52px;align-items:start}
.mapcol{position:sticky;top:92px}
.regcol{display:grid;grid-template-columns:1fr 1fr;gap:26px 22px}
.reg h3{font-size:0.7188rem;font-weight:700;letter-spacing:.11em;text-transform:uppercase;
  color:var(--ink3);padding-bottom:8px;border-bottom:1px solid var(--line2);margin-bottom:3px}
.reglist{display:flex;flex-wrap:wrap;gap:5px 6px;padding-top:6px}
.reglist a{font-size:0.8438rem;font-weight:600;text-decoration:none;color:var(--ink2);
  border:1px solid var(--line);border-radius:999px;padding:5px 11px;
  transition:background .14s,color .14s,border-color .14s}
.reglist a:hover,.reglist a:focus-visible{background:var(--accent);border-color:var(--accent);color:#fff}
.jmap .pf.lit path{fill:var(--accent)}
@media(max-width:1000px){
  .mapgrid{grid-template-columns:1fr;gap:30px}
  .mapcol{position:static;max-width:420px;margin:0 auto}
}

/* a single prefecture */
.prefhead{display:grid;grid-template-columns:1fr 260px;gap:44px;align-items:start;margin-bottom:34px}
.prefmap{border:1px solid var(--line);border-radius:14px;padding:14px;background:var(--soft)}
.prefmap .jmap .pf path{fill:#DCDCD8}
.prefmap .jmap .pf.on path{fill:var(--accent)}
.prefmap .jmap .inset,.prefmap .jmap .insetlab{display:none}
@media(max-width:1000px){
  .prefhead{grid-template-columns:1fr;gap:24px}
  .prefmap{max-width:240px}
}

/* ---------- the notebook: four trips, French only ---------- */
.trips{display:grid;grid-template-columns:1fr 1fr;gap:34px 30px;margin-top:8px}
.trip{margin:0}
/* An odd trip out takes the whole row rather than leaving a gap beside it, as a
   row: picture on one side, title on the other. A full-width band was tried first
   and cropped a 4:3 photograph down to a strip. */
.trip.wide{grid-column:1/-1;display:grid;gap:30px;
  grid-template-columns:minmax(0,1fr) minmax(0,1fr);align-items:center}
.trip.wide .triptext{margin-top:0}
.trip.wide .triptext h2{font-size:2rem}
.trip.wide .tripline{font-size:1rem;margin-top:14px}
.tripshot{display:block;border-radius:14px;overflow:hidden;background:var(--soft);
  aspect-ratio:3/2}
.tripshot img{width:100%;height:100%;object-fit:cover;display:block;
  transition:transform .6s cubic-bezier(.2,.8,.2,1)}
.trip:hover .tripshot img{transform:scale(1.03)}
.triptext{margin-top:14px}
.triptext h2{font-size:1.5rem;font-weight:800;letter-spacing:-.028em;line-height:1.15;
  margin:3px 0 0}
.triptext h2 a{text-decoration:none}
.triptext h2 a:hover{color:var(--accent)}
/* The itinerary itself. A card that says "6 étapes" says nothing about the trip. */
/* The card wears the trip page's masthead, at card scale, so the index and the
   journeys read as one thing. */
.bigdate.card{margin:0 0 -.02em}
.bigdate.card span{font-size:0.9375rem;font-weight:700;letter-spacing:.01em;
  text-transform:uppercase}
.bigdate.card span:empty::before{content:"\00a0"}
.bigdate.card b{font-size:clamp(2.5rem,4.6vw,3.5rem)}
.trip.wide .bigdate.card b{font-size:clamp(3rem,5.6vw,4.5rem)}
.tripline{color:var(--ink2);font-size:0.9375rem;line-height:1.5;margin-top:8px;
  max-width:46ch}
.tripline span{white-space:nowrap}

/* The head used to end flush against the body's rule. With the stop rail in it,
   the chips were sitting on the hairline. */
.triphead{padding-bottom:26px}
/* The date, set as the masthead of the trip. Light rather than black: it dominates
   by size while the place name still leads on contrast, which is what keeps two
   large blocks from fighting each other. */
/* The month stacks above the year rather than sitting beside it. Side by side,
   "Mars 2025" fitted one line and "Hiver 2019-20" did not, so the two trips wore
   different mastheads. */
/* #D2D2D9 first, which measures 1.50:1 on white. Every grey in :root clears 4.5, so
   this was the one text colour on the site set outside the palette and below it: a
   126px year that reads as a watermark rather than as the date it is. #94949B is
   3.01:1, the threshold for text this size, and still a clear step lighter than the
   month beside it at 4.70. Check 90 holds every hand-written text colour to it. */
.bigdate{display:flex;flex-direction:column;align-items:flex-start;
  margin:14px 0 -.04em;font-weight:800;letter-spacing:-.05em;line-height:.86;
  color:#94949B}
.bigdate span{font-size:clamp(1.375rem,3.2vw,2.5rem);letter-spacing:-.03em;
  color:var(--ink3);font-weight:700}
/* nowrap: a hyphen is a break opportunity, so "hiver 2019-20" came apart into
   "2019-" and "20" on two lines and the masthead ate the screen. */
.bigdate b{font-size:clamp(3.25rem,10.5vw,8rem);font-weight:800;white-space:nowrap;
  font-variant-numeric:lining-nums tabular-nums}
.triphead h1{font-size:clamp(1.875rem,4.4vw,3.25rem);font-weight:800;
  letter-spacing:-.035em;line-height:1.05;margin-top:6px}
/* the writing on the left, a locator that rides down beside it on the right */
/* The stops, as one line you can scan and jump from. It lights up under the stop
   you are reading, so the page always answers "where am I" without a scrollbar. */
.triproute{display:flex;flex-wrap:wrap;gap:7px;margin:22px 0 6px}
.triproute a{display:inline-flex;align-items:center;gap:7px;padding:6px 13px 6px 7px;
  border:1px solid var(--line);border-radius:999px;font-size:0.8125rem;
  color:var(--ink2);text-decoration:none;line-height:1.2;
  transition:border-color .2s,color .2s,background .2s}
.triproute a i{display:grid;place-items:center;width:18px;height:18px;border-radius:50%;
  background:var(--soft);color:var(--ink3);font-style:normal;font-size:0.625rem;
  font-weight:800;transition:background .2s,color .2s}
.triproute a:hover{border-color:var(--ink3);color:var(--ink)}
.triproute a.on{border-color:var(--accent);color:var(--ink);background:#fff}
.triproute a.on i{background:var(--accent);color:#fff}

/* Sixteen old /blog/ URLs now land on a #stop. Without this the sticky header
   covers the heading they were sent to. */
.stop{scroll-margin-top:96px}
.tripbody{display:grid;grid-template-columns:minmax(0,1fr) minmax(360px,440px);
  gap:52px;align-items:start;padding-bottom:24px}
.stop{padding:52px 0 0;border-bottom:0}
.stop h2{font-size:1.75rem;font-weight:800;letter-spacing:-.03em;line-height:1.1;
  margin:4px 0 0}
.stopsub{color:var(--ink3);font-size:1.0625rem;margin-top:5px}
.stoptext{max-width:660px;margin-top:18px}
.stoptext p{margin-top:14px}
/* Direct child only. Unscoped, this also matched the first paragraph inside .rest,
   so "Lire la suite" revealed text that ran straight on from the sentence above it
   with no paragraph break at all. */
.stoptext > p:first-child{margin-top:0}
.stoptext .rest{display:none}
/* display cannot transition, so the reveal is a keyframe: the rest of the piece
   arrives rather than appearing. */
.stoptext .rest.open{display:block;animation:unfold .45s cubic-bezier(.2,.8,.2,1) both}
@keyframes unfold{from{opacity:0;transform:translateY(-6px)}to{opacity:1;transform:none}}
.moretext,.moreshots{margin-top:12px;font:inherit;font-size:0.8125rem;font-weight:600;
  color:var(--ink2);background:none;border:0;border-bottom:1.5px solid var(--accent);
  padding:0 0 2px;cursor:pointer;display:inline-block}
.moretext:hover,.moreshots:hover{color:var(--ink)}
/* Deliberately small, and clamped to two rows. The gallery is an index of the stop,
   not the stop itself: click one and the lightbox gives you the full frame. Every
   photograph stays in the page so the lightbox can walk the whole stop. */
.stopgal{margin-top:22px}
/* overflow:clip, not hidden. hidden makes a scroll container, and tabbing to one of
   the clipped thumbnails made the browser scroll the box itself by 600px to reveal
   it, with no scrollbar and no way back: the contact sheet was left starting halfway
   down with its first rows gone. clip cannot scroll. hidden stays as the fallback
   for browsers that do not know the keyword. */
.stopgal .stopshots{max-height:198px;overflow:hidden;overflow:clip}
.stopgal.open .stopshots{max-height:none}
.stopshots{display:grid;grid-template-columns:repeat(auto-fill,minmax(96px,1fr));
  gap:6px;columns:auto}
.stopshots .tile{margin:0;display:block;border-radius:6px;overflow:hidden;
  background:var(--soft);aspect-ratio:1}
.stopshots .tile img{width:100%;height:100%;object-fit:cover;display:block;
  transition:transform .4s cubic-bezier(.2,.8,.2,1)}
.stopshots .tile:hover img{transform:scale(1.08)}
/* One map, and a window that flies over it. Sixteen separate images could only
   cross-fade; this travels. The map is laid out at its own CSS width and never
   scaled — a map is typeset for the width it is drawn at, and shrinking a 1280px
   map into a 300px panel is what made every label unreadable. */
/* Nearly the whole window. A 300px square read as a thumbnail pinned to the margin;
   at this height it is a companion pane, and the flight between stops has room to
   be a flight. 84px is the sticky header plus a little air. */
.tripmap{position:sticky;top:84px;height:calc(100vh - 116px);min-height:420px;
  border:1px solid var(--line);border-radius:16px;overflow:hidden;
  background:var(--soft);box-shadow:0 1px 2px rgba(17,17,19,.04)}
.mcam{position:absolute;left:0;top:0;will-change:transform;
  transition:transform 1.5s cubic-bezier(.35,.72,.15,1)}
.mcam img{display:block;width:100%;height:100%}
/* A marker that points at the place rather than sitting on top of it. Centred on
   the coordinate, the disc landed squarely over Mapbox's own label and Port Barton
   read as "Port (1) ton". It now stands above the point, with a tail on it. */
.fpin{position:absolute;z-index:2;width:20px;height:20px;margin:-27px 0 0 -10px;
  border-radius:50%;background:#fff;border:2px solid var(--ink3);color:var(--ink2);
  display:grid;place-items:center;font-size:0.625rem;font-weight:800;font-style:normal;
  transform-origin:50% 130%;
  transition:background .3s,border-color .3s,color .3s,transform .3s}
.fpin::after{content:"";position:absolute;left:50%;top:15px;width:2px;height:8px;
  background:var(--ink3);transform:translateX(-50%);transition:background .3s}
.fpin i{font-style:normal;position:relative;z-index:1}
.fpin.on{background:var(--accent);border-color:#fff;color:#fff;transform:scale(1.25);
  box-shadow:0 2px 8px rgba(207,66,42,.45)}
.fpin.on::after{background:var(--accent)}
/* which stop the map is showing, in its own corner */
.mnow{position:absolute;left:14px;bottom:14px;right:14px;z-index:3;width:fit-content;
  max-width:calc(100% - 28px);display:flex;align-items:baseline;
  gap:9px;background:rgba(255,255,255,.94);backdrop-filter:blur(6px);
  padding:8px 13px;border-radius:10px;box-shadow:0 2px 10px rgba(17,17,19,.1)}
/* "Vang Vieng et le lac Nam Ngum" is as long as the panel is wide */
.mnow b{font-size:0.9375rem;font-weight:700;letter-spacing:-.015em;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.mnow span{flex:none}
.mnow span{font-size:0.75rem;color:var(--ink3);font-variant-numeric:tabular-nums}
.mapcredit{position:absolute;right:7px;bottom:6px;margin:0;font-size:0.5625rem;
  letter-spacing:.02em;color:var(--ink3);background:rgba(255,255,255,.72);
  padding:1px 5px;border-radius:4px;z-index:3}
@media(prefers-reduced-motion:reduce){ .mcam{transition:none} }

@media(max-width:1000px){
  .trip.wide{grid-template-columns:1fr;gap:14px}
  .trip.wide .triptext h2{font-size:1.5rem}
  .tripbody{grid-template-columns:1fr;gap:0}
  /* Stacked, the map is the second grid item and so landed at the very bottom of
     the page, below every stop: you met the route after you had read the trip.
     order puts it first. Not sticky here, because the narrow header wraps to a
     height nothing can offset against reliably. */
  .tripmap{position:relative;top:0;order:-1;height:260px;min-height:0;margin:0 0 30px}
}
@media(max-width:900px){
  .trips{grid-template-columns:1fr;gap:26px}
  .stop{padding-top:38px}
  .stoptext{max-width:none}
  .stopshots{grid-template-columns:repeat(auto-fill,minmax(78px,1fr))}
}

/* ---------- books: a timeline ---------- */
/* 992, not 900: the covers were rendering at 166px inside a 1124px content area,
   from files that are 1000 to 1200px wide. A page about books was showing them at
   under a third of the resolution it had already downloaded, with 220px of the
   wrap left empty beside it. The extra 92px all goes to the cover column, so the
   text measure is unchanged at 576px. The covers carry no srcset, so this costs
   nothing to serve. */
.timeline{position:relative;max-width:992px}
.timeline:before{content:"";position:absolute;left:96px;top:8px;bottom:8px;width:1px;
  background:var(--line2)}
.ev{position:relative;display:grid;grid-template-columns:96px 260px 1fr;gap:30px;
  align-items:start;padding:0 0 44px 0}
.ev:last-child{padding-bottom:0}
.ev:after{content:"";position:absolute;left:92px;top:7px;width:9px;height:9px;border-radius:50%;
  background:var(--bg);border:2px solid var(--line2)}
.ev.soon:after{border-color:var(--accent);background:var(--accent)}
.evyr{text-align:right;padding-right:22px;font-size:0.8125rem;font-weight:700;color:var(--ink3);
  display:flex;flex-direction:column;align-items:flex-end;gap:7px;line-height:1.3}
.evcover{border-radius:10px;overflow:hidden;background:var(--soft);border:1px solid var(--line)}
.evcover img,.evcover .mock{width:100%;height:auto;display:block}
.ev h2{font-size:1.3125rem;font-weight:800;letter-spacing:-.028em;line-height:1.2}
.ev .bsub{font-size:0.9062rem;color:var(--ink3);margin-top:3px}
.ev .btext{font-size:0.9062rem;color:var(--ink2);line-height:1.65;margin-top:10px;max-width:56ch}
.ev .bpub{font-size:0.8125rem;color:var(--ink3);margin-top:12px}
.ev .bpub a{font-weight:600;color:var(--ink2);text-decoration:none;border-bottom:1.5px solid var(--accent)}
.ev.secret .evcover{opacity:.5}
/* "En écriture" is a state, not a title. Italic says so without a second label. */
.ev.secret h2{color:var(--ink3);font-style:italic}
.ev.secret .evcover{border-style:dashed}
/* A label, not a pill. The filled capsule was the only one of its kind on the site,
   and its padding pushed "À paraître" past the 74px this column offers, so it broke
   across two lines with the "À" stranded against the right edge. Without the fill it
   fits, it stops shouting, and it matches every other small label here. The timeline
   dot beside it is already accent-coloured, so the two now agree. */
.badge{display:inline-block;font-size:0.6562rem;font-weight:700;letter-spacing:.08em;
  text-transform:uppercase;color:var(--accent);white-space:nowrap}
.ev.secret .badge{color:var(--ink3)}

/* home: a low row of spines instead of a tall shelf */
/* Aligned by height, not width, the way books actually stand on a shelf. It used to
   force every cover into a 4:3 landscape box and crop to fill, which was harmless
   while the covers were lookalike placeholders and destroyed them the moment the real
   ones arrived: two are portrait, so Abandoned Japan showed a dark blur and Corée du
   Nord a vertical slice, every title cropped away. Nothing is cropped now, and the
   varied widths are the point. */
.strip{display:flex;gap:16px;flex-wrap:wrap;align-items:flex-start}
/* flex:0 0 auto, and no max-width on the image: an auto-width flex item plus a
   percentage max-width on its child resolve against each other and collapse to 2px. */
.spine{text-decoration:none;flex:0 0 auto}
.spine img{height:132px;width:auto;border-radius:8px;
  border:1px solid var(--line);transition:transform .25s}
.spine:hover img{transform:translateY(-3px)}
.spine span{display:block;font-size:0.8125rem;font-weight:600;margin-top:8px;
  line-height:1.35;color:var(--ink2);max-width:172px}

/* ---------- software: an icon per group, a link per project ---------- */
.swhead .ico{width:26px;height:26px;color:var(--accent);
  margin:13px 0 23px}                 /* 26 + 26 = the 52px a mark occupies */
.swlist li a,.swlist li>.row{display:grid;
  grid-template-columns:minmax(0,230px) minmax(0,1fr);gap:22px;align-items:baseline;
  text-decoration:none;color:inherit;width:100%}
.swlist li{border-bottom:1px solid var(--line)}
.swlist li a,.swlist li>.row{padding:16px 4px}
.swlist li a{transition:padding-left .16s}
.swlist li a:hover{padding-left:10px}
.swlist li a:hover b{color:var(--accent)}
.swlist .ext{font-size:0.6875rem;color:var(--ink3);margin-left:6px;vertical-align:2px}
.swlist li a:hover .ext{color:var(--accent)}
@media(max-width:900px){
  .timeline:before,.ev:after{display:none}
  .ev{grid-template-columns:1fr;gap:12px;padding-bottom:34px}
  .evyr{text-align:left;padding:0;flex-direction:row;align-items:center}
  .evcover{max-width:200px}
  .swlist li a,.swlist li>.row{grid-template-columns:1fr;gap:4px}
}

/* ---------- prints: three steps ---------- */
.steps{list-style:none;counter-reset:s;display:grid;gap:2px;max-width:760px}
.steps li{counter-increment:s;display:grid;grid-template-columns:44px 1fr;gap:18px;
  align-items:baseline;padding:20px 0;border-bottom:1px solid var(--line)}
.steps li:before{content:counter(s);font-size:0.8125rem;font-weight:700;color:var(--accent);
  border:1px solid var(--line2);border-radius:50%;width:30px;height:30px;
  display:grid;place-items:center}
.steps li b{display:block;font-size:1.0625rem;font-weight:700;letter-spacing:-.02em;margin-bottom:4px}
.steps li span{font-size:0.9375rem;color:var(--ink2);line-height:1.65}
.steps li b,.steps li span{grid-column:2}
@media(max-width:640px){.steps li{grid-template-columns:32px 1fr;gap:12px}}

/* ---------- a finger is not a cursor ---------- */
/* The phone nav was given 44px targets on purpose, and everything standing beside it
   kept whatever its text happened to measure: the language switcher 28px, and
   "Lire la suite" and "Voir les 44 photographies" 24 — the two controls that actually
   open the notebook. Measured in a 390px frame, not guessed.

   Padding was tried first and is wrong: .triproute already sets its own, so the rule
   replaced it and bought nothing, and the negative margin meant to hide the growth
   over-collapsed and pulled the whole page up by 170px. An absolutely positioned
   ::after is outside the flow — it cannot move a single thing — and a tap inside it
   still lands on the link that owns it.

   The stop chips are left at 32px deliberately: they sit in a wrapped row 7px apart,
   so a 44px target would overlap its neighbour above and start stealing taps. They
   are 77 to 128px wide, which is the dimension a thumb misses on. */
@media (pointer:coarse){
  .langs a,.moretext,.moreshots,.chaplink{position:relative}
  .langs a::after,.moretext::after,.moreshots::after,.chaplink::after{
    content:"";position:absolute;left:0;right:0;top:50%;height:44px;
    transform:translateY(-50%)}
}

/* ---------- respect a reduced-motion preference ---------- */
/* 17 transitions and 19 transforms, most of them on photographs that zoom under
   the cursor. For anyone with vestibular sensitivity that is not decoration, it is
   a problem. Honour the system setting: keep every state change, drop the movement. */
@media (prefers-reduced-motion: reduce){
  *,*::before,*::after{
    animation-duration:.001ms !important;animation-iteration-count:1 !important;
    transition-duration:.001ms !important;scroll-behavior:auto !important}
  /* Every :hover rule that moves something has to be listed here. Seven were not:
     the story page's own frames and hero, the season strip, the big software card,
     both lightbox arrows and the country chip. A hand-kept list drifts, so check 38
     reads the stylesheet and fails if one is missing from this block. */
  .grid .tile:hover img,.mosaic .tile:hover img,.scard:hover img,.spine:hover img,
  .chapshots .tile:hover img,.openhero .tile:hover img,.sstrip a:hover img,
  .trip:hover .tripshot img,.stopshots .tile:hover img{transform:none}
  .stoptext .rest.open{animation:none}
  .cta a:hover,.el:hover,.swt:hover,.ev:hover,.clinks a:hover,.swbig:hover,
  #lb .prev:hover,#lb .next:hover,.grid .tile:hover .cc{transform:none}
}

/* ---------- print (pt on purpose) ---------- */
/* Picture editors print things. A prefecture page on paper should be the
   photographs and the facts, not the navigation and a map of Japan. */
@media print{
  header.nav,footer,.skip,#lb,.prefmap,.mapgrid,.cta,.more,.crumb,.swteaser,
  .endlinks,.clinks,.seasonnav,.scards,.wayh2,.steps li:before,
  /* A trip page on paper is the writing and the photographs. The rail is a jump
     control with nothing to jump to, and the map is a window that pans: printed, it
     is whatever crop the reader happened to leave it on. */
  .triproute,.tripmap,.moretext,.moreshots{display:none !important}
  /* Otherwise the page prints its first paragraph per stop and silently drops the
     rest, because the rest of the article is display:none until a button is clicked. */
  /* A 9rem year in pale grey is a screen device: on paper it is most of the first
     page, printed in a tone most printers turn to nothing. */
  .bigdate,.bigdate.card{color:#000 !important;margin:0 !important}
  .bigdate b{font-size:22pt !important}
  .bigdate span{font-size:11pt !important;color:#000 !important}
  .stoptext .rest,.stoptext .rest.open{display:block !important}
  .stopgal .stopshots,.stopgal.open .stopshots{
    max-height:none !important;overflow:visible !important}
  .tripbody{display:block !important}
  body{background:#fff;color:#000;font-size:11pt}
  .wrap,.prose{max-width:none;padding:0}
  section{padding:0 0 18pt;border:none;break-inside:avoid}
  section.alt{background:none}
  .head h1,.head h2{font-size:20pt;margin:0 0 6pt}
  .head .sub,.head p{font-size:10pt}
  .eyebrow{font-size:8pt;letter-spacing:.08em}
  .grid{columns:3;column-gap:8pt}
  .grid .tile{break-inside:avoid;margin-bottom:8pt;border-radius:0}
  .grid .tile img{border-radius:0}
  .timeline:before,.ev:after{display:none}
  .ev{grid-template-columns:70pt 110pt 1fr;gap:14pt;padding-bottom:16pt}
  /* a printed page loses its links, so spell out where the important ones went */
  .bpub a:after,.hero .lede a:after{content:" (" attr(href) ")";
    font-size:8pt;color:#555;word-break:break-all}
  .use a:after{content:" (" attr(data-print) ")";
    font-size:8pt;color:#555;word-break:break-all}
  a{text-decoration:none;color:#000}
  .use{border-top:1pt solid #999;padding-top:8pt;font-size:9pt}
  @page{margin:14mm}
}

/* --- Japanese typography ---------------------------------------------------
   Wide tracking on a small uppercase label is a Latin idiom: uppercase does
   nothing to kana or kanji and the extra space only makes Japanese look loose.
   Last in the file so it wins over the per-component tracking above. */
:lang(ja) .eyebrow,:lang(ja) .crumb,:lang(ja) .ways,:lang(ja) .open .ways{letter-spacing:.02em}
:lang(ja) .reg h3{letter-spacing:.05em}

main{flex:1 0 auto}
