/*! karla-home.css — the home page, Concept D.
    The page is built from WordPress blocks now. Each section is a Group block
    carrying `plate` plus one modifier; the two-column sections are Columns
    blocks carrying `in`. These selectors deliberately target BOTH the plain
    class and the core block wrapper, so the same rules hold whether the markup
    came from the editor or from a template.
    Tokens live in the child theme style.css. */

body.kb-ink-home{margin:0;background:var(--k-paper);color:var(--k-ink);font-family:var(--k-sans);
  font-weight:300;font-size:16px;line-height:1.8;-webkit-font-smoothing:antialiased;overflow-x:hidden}
body.kb-ink-home *{box-sizing:border-box}
body.kb-ink-home img{max-width:100%;height:auto;display:block}
body.kb-ink-home h1,body.kb-ink-home h2,body.kb-ink-home h3{font-family:var(--k-display);font-weight:400;
  margin:0;line-height:1;letter-spacing:-.015em;text-wrap:balance;color:var(--k-ink)}
body.kb-ink-home p{margin:0 0 1.2em}
.cap{font-size:.78rem;letter-spacing:.18em;text-transform:uppercase;color:var(--k-grey)}

html:has(body.kb-ink-home){scroll-behavior:smooth}

#ink{position:fixed;inset:-90px;width:calc(100% + 180px);height:calc(100% + 180px);z-index:0;
  pointer-events:none;filter:blur(22px) saturate(1.12)}
.veil{position:fixed;inset:0;z-index:1;pointer-events:none;
  background:radial-gradient(78% 62% at 30% 56%,rgba(247,244,239,.90) 0%,rgba(247,244,239,.52) 46%,rgba(247,244,239,0) 78%),
             linear-gradient(180deg,rgba(247,244,239,.86) 0,rgba(247,244,239,0) 16%),
             linear-gradient(0deg,rgba(247,244,239,.80) 0,rgba(247,244,239,0) 14%)}
main{position:relative;z-index:2}
/* same safety net as the inner pages: never honour a stale height attribute */
body.kb-ink-home img{max-width:100%;height:auto}

/* ---- fixed furniture ---- */
.brand{position:fixed;top:30px;left:clamp(22px,6vw,90px);z-index:30;font-family:var(--k-display);font-size:1.15rem}
.brand a{color:inherit;text-decoration:none}
.brand a:hover{color:var(--k-coral)}
/* The language pair lives in the right gutter, stacked above the pause
   control. Bottom left it sat inside the reading column, so it crossed the
   body copy at almost every scroll position; the gutter is already reserved
   by every plate for the index rail, so nothing has to move around it. */
.lang{position:fixed;bottom:74px;right:clamp(22px,3vw,36px);z-index:30;
  display:flex;gap:8px;align-items:center;justify-content:flex-end}
.lang a{text-decoration:none;color:var(--k-grey);padding:11px 2px;min-height:44px;display:inline-flex;align-items:center}
.lang a.is-on{color:var(--k-ink)}
.lang a:hover{color:var(--k-coral)}
body.kb-ink-home #trp-floater-ls,
body.kb-ink-home .trp-floating-switcher{display:none !important}

.idx{position:fixed;right:clamp(22px,3vw,36px);top:50%;transform:translateY(-50%);z-index:30;
  display:flex;flex-direction:column;gap:2px;align-items:flex-end;text-align:right;max-width:210px}
.idx a{display:flex;align-items:center;justify-content:flex-end;gap:11px;text-decoration:none;
  color:var(--k-grey);font-size:.75rem;letter-spacing:.15em;text-transform:uppercase;
  padding:9px 0;min-height:40px;box-sizing:content-box;transition:color .45s}
.idx a span{display:block;line-height:1.35}
.idx a i{display:block;width:15px;height:1px;background:currentColor;opacity:.45;flex:0 0 auto;
  transition:width .45s,background .45s,opacity .45s}
.idx a:hover,.idx a.on{color:var(--k-ink)}

/* Frosted glass behind the rail.
   Artwork bleeds under the rail on purpose, so instead of hiding it the rail
   frosts whatever passes beneath: a real backdrop blur plus a light paper
   tint. The panel is soft masked so it reads as a haze, not a rectangle.
   Browsers without backdrop-filter fall back to a plain tint, which is why the
   tint is on the base rule and only strengthened inside @supports. */
.idx{isolation:isolate}
.idx::before{content:"";position:absolute;z-index:-1;pointer-events:none;
  inset:-30px -42px;border-radius:26px;
  background:rgba(247,244,239,.82)}
@supports ((backdrop-filter:blur(1px)) or (-webkit-backdrop-filter:blur(1px))){
  .idx::before{
    background:rgba(247,244,239,.46);
    -webkit-backdrop-filter:blur(20px) saturate(1.06);
            backdrop-filter:blur(20px) saturate(1.06);
    /* The blur has a hard rectangular boundary, which drew a visible seam
       across the artwork. It is feathered on both axes: two linear masks
       intersected, so the middle stays solid and all four edges fade out. A
       single radial mask was tried first and could not cover a tall narrow
       panel without the end labels falling into the fade. The -webkit- form
       is for Blink and WebKit, the standard form for Gecko. */
    -webkit-mask-image:linear-gradient(90deg,rgba(0,0,0,0) 0,#000 15%,#000 85%,rgba(0,0,0,0) 100%),
                       linear-gradient(180deg,rgba(0,0,0,0) 0,#000 11%,#000 89%,rgba(0,0,0,0) 100%);
            mask-image:linear-gradient(90deg,rgba(0,0,0,0) 0,#000 15%,#000 85%,rgba(0,0,0,0) 100%),
                       linear-gradient(180deg,rgba(0,0,0,0) 0,#000 11%,#000 89%,rgba(0,0,0,0) 100%);
    -webkit-mask-composite:source-in;
            mask-composite:intersect;
  }
}
.idx a.on i{width:42px;background:var(--k-coral);opacity:1}

.motion{position:fixed;bottom:30px;right:clamp(22px,3vw,36px);z-index:31;
  background:rgba(247,244,239,.86);backdrop-filter:blur(6px);border:0;font-family:var(--k-sans);
  font-size:.78rem;letter-spacing:.15em;text-transform:uppercase;color:var(--k-grey);cursor:pointer;
  padding:11px 14px;min-height:44px}
.motion:hover{color:var(--k-ink)}
.skip{position:absolute;left:-9999px;top:0;z-index:60;background:var(--k-ink);color:var(--k-paper);
  padding:14px 22px;font-size:.8rem;letter-spacing:.14em;text-transform:uppercase;text-decoration:none}
.skip:focus{left:12px;top:12px}
body.kb-ink-home :focus-visible{outline:2px solid var(--k-coral);outline-offset:4px;border-radius:2px}

/* ---- the plates ---- */
body.kb-ink-home .plate{min-height:100svh;display:grid;place-items:center;position:relative;
  padding:14vh clamp(22px,6vw,90px);margin:0;max-width:none}
/* Core sometimes wraps group children in an inner container and sometimes
   does not, depending on the layout support in play. Match both. */
body.kb-ink-home .plate > .wp-block-group__inner-container{width:100%}
body.kb-ink-home .plate .in,
body.kb-ink-home .plate > .wp-block-group__inner-container > *,
body.kb-ink-home .plate > *{width:100%;max-width:1080px;margin-left:auto;margin-right:auto}

/* Columns blocks used as the two-column grid. Core makes them flex with
   percentage bases; the design needs a real grid, so both are overridden. */
body.kb-ink-home .plate .in.wp-block-columns{display:grid;gap:8vw;align-items:center;margin-bottom:0}
body.kb-ink-home .plate .in.wp-block-columns > .wp-block-column{flex-basis:auto !important;
  min-width:0;margin:0;flex-grow:0}

/* 1 hero */
body.kb-ink-home .hero .in.wp-block-columns{grid-template-columns:minmax(0,1fr) minmax(220px,300px);
  gap:70px;align-items:end}
body.kb-ink-home .hero h1{font-size:clamp(3rem,8.6vw,7.8rem);line-height:.9}
body.kb-ink-home .hero h1 em{font-style:italic;color:var(--k-coral)}
body.kb-ink-home .hero .wp-block-column:last-child{text-align:right}
body.kb-ink-home .hero .wp-block-column:last-child p{color:var(--k-grey);font-size:.95rem;
  max-width:26ch;margin-left:auto}

/* 2 statement */
body.kb-ink-home .say > *,
body.kb-ink-home .say .in{max-width:900px}
body.kb-ink-home .say p{font-family:var(--k-display);font-size:clamp(1.6rem,4.4vw,3.5rem);
  line-height:1.2;margin:0;color:var(--k-ink)}
body.kb-ink-home .say p em{font-style:normal;color:var(--k-grey)}

/* 3 to 5, the practices */
body.kb-ink-home .w .in.wp-block-columns{grid-template-columns:minmax(0,1fr) minmax(0,1fr)}
body.kb-ink-home .w .no{font-family:var(--k-display);font-style:italic;font-size:1rem;
  color:var(--k-coral);margin:0 0 20px}
body.kb-ink-home .w h2{font-size:clamp(1.9rem,4.4vw,3.4rem);margin-bottom:22px}
body.kb-ink-home .w p{color:var(--k-grey);max-width:40ch;font-size:.98rem}
body.kb-ink-home .w .wp-block-image{display:flex;justify-content:center;margin:0}
body.kb-ink-home .w .wp-block-image img{max-height:60vh;width:auto}

/* ---- full bleed artwork ----
   A practice plate can carry its picture off the edge of the screen instead of
   sitting politely inside the column. Put `bleed-r` (or `bleed-l`) on the Group
   block alongside `plate w`. The picture escapes the plate padding, runs past
   the viewport edge and gets a lighter touch so the reading column still wins.
   The index rail sits in the right gutter, so a right bleed is masked back to
   transparent under it rather than running beneath the labels. */
/* The figure is the bleeding box: it starts at the reading column's inner
   edge and runs past the side of the screen. The PICTURE is centred inside
   it. As a block the picture pinned itself to the figure's left edge whatever
   side it was bleeding to, which left a 440px hole between a narrow artwork
   and the words on a left bleed, and stopped a right bleed reaching the edge
   of the screen at all. */
body.kb-ink-home .plate.bleed-r .wp-block-image,
body.kb-ink-home .plate.bleed-l .wp-block-image{
  position:relative; z-index:0; margin:0;
  display:flex; justify-content:center; align-items:center;
  width:auto; max-width:none;
}
body.kb-ink-home .plate.bleed-r .wp-block-image > img,
body.kb-ink-home .plate.bleed-l .wp-block-image > img{
  max-height:none; width:auto;
  height:clamp(420px,72vh,900px);
  max-width:none;
  opacity:.92;
}
@media(min-width:901px){
  body.kb-ink-home .plate.bleed-r .in.wp-block-columns{ gap:4vw }
  body.kb-ink-home .plate.bleed-r .wp-block-column:last-child{
    margin-right:calc(-1 * clamp(210px,17vw,290px));   /* out through the plate padding */
    overflow:visible;
  }
  body.kb-ink-home .plate.bleed-r .wp-block-image{
    margin-right:-14vw;                                 /* and past the viewport edge */
  }
  /* The soft edge belongs on the PICTURE, not on the figure. On the figure it
     also clipped .kb-motes, which is a child of it, so every floating piece
     was cut in half at the mask edge and none of them could travel out of the
     picture's own box. */
  body.kb-ink-home .plate.bleed-r .wp-block-image > img{
    -webkit-mask-image:linear-gradient(90deg,#000 0,#000 72%,transparent 97%);
            mask-image:linear-gradient(90deg,#000 0,#000 72%,transparent 97%);
  }
  body.kb-ink-home .plate.bleed-l .wp-block-column:first-child{
    margin-left:calc(-1 * clamp(40px,6vw,90px));
    overflow:visible;
  }
  body.kb-ink-home .plate.bleed-l .wp-block-image{
    margin-left:-12vw;
  }
  body.kb-ink-home .plate.bleed-l .wp-block-image > img{
    -webkit-mask-image:linear-gradient(270deg,#000 0,#000 72%,transparent 97%);
            mask-image:linear-gradient(270deg,#000 0,#000 72%,transparent 97%);
  }
}
@media(min-width:901px){
  body.kb-ink-home .plate.bleed-r .in,
  body.kb-ink-home .plate.bleed-l .in{position:relative;z-index:2}
}

@media(max-width:900px){
  /* On a narrow screen the picture LEADS its section: full strength, above
     the words it belongs to, not a half faded wash behind them. The right
     bleed puts its picture in the second column, so that column is pulled to
     the front of the stack; the left bleed already leads with it. */
  body.kb-ink-home .plate.bleed-r .in.wp-block-columns > .wp-block-column:last-child{order:-1}
  body.kb-ink-home .plate.bleed-r .wp-block-image,
  body.kb-ink-home .plate.bleed-l .wp-block-image{
    margin:0 auto 4px; width:100%; max-width:none;
    display:flex; justify-content:center;
  }
  body.kb-ink-home .plate.bleed-r .wp-block-image > img,
  body.kb-ink-home .plate.bleed-l .wp-block-image > img{
    height:auto; width:auto; max-width:100%; max-height:52vh; opacity:1;
  }
}

/* 6 biography */
body.kb-ink-home .b .in.wp-block-columns{grid-template-columns:minmax(0,300px) minmax(0,1fr);
  align-items:start}
body.kb-ink-home .b h2{font-size:clamp(1.8rem,3.8vw,2.9rem);margin-bottom:26px}
body.kb-ink-home .b p{color:var(--k-grey);max-width:50ch;font-size:.96rem}
body.kb-ink-home .b .wp-block-image{margin:0 0 13px}
body.kb-ink-home .b .wp-block-image img{filter:grayscale(1) contrast(1.05);width:100%}

/* 7 close */
body.kb-ink-home .c{text-align:center}
body.kb-ink-home .c h2{font-family:var(--k-display);font-style:italic;
  font-size:clamp(1.9rem,5.6vw,4.4rem);line-height:1.16;max-width:17ch;margin:0 auto}

/* ---- Table blocks used for the detail rows ---- */
body.kb-ink-home .meta{margin:32px 0 0}
body.kb-ink-home .meta table{border-collapse:collapse;width:100%;border:0}
body.kb-ink-home .meta td{border:0;border-top:1px solid var(--k-hair);padding:10px 16px 10px 0;
  font-size:.86rem;color:var(--k-ink);vertical-align:top}
body.kb-ink-home .meta td:first-child{width:38%;color:var(--k-grey);letter-spacing:.1em;
  text-transform:uppercase;font-size:.72rem;padding-top:14px}
body.kb-ink-home .b .meta td:first-child{width:34%}
body.kb-ink-home .meta figcaption{display:none}

/* ---- Button blocks used for the links ---- */
body.kb-ink-home .wp-block-buttons{margin:28px 0 0;gap:14px}
body.kb-ink-home .wp-block-button__link{display:inline-block;background:none;color:var(--k-ink);
  text-decoration:none;font-family:var(--k-sans);font-size:.8rem;letter-spacing:.16em;
  text-transform:uppercase;border:0;border-bottom:1px solid var(--k-coral);border-radius:0;
  padding:0 0 4px;transition:.3s}
body.kb-ink-home .wp-block-button__link:hover{color:var(--k-coral);background:none}
body.kb-ink-home .c .wp-block-buttons{justify-content:center;margin-top:48px}
body.kb-ink-home .c .wp-block-button__link{border:1px solid var(--k-ink);padding:18px 44px}
body.kb-ink-home .c .wp-block-button__link:hover{background:var(--k-coral);border-color:var(--k-coral);
  color:var(--k-paper)}

/* ---- foot ---- */
.kb-foot{position:relative;z-index:2;padding:26px clamp(22px,6vw,90px);border-top:1px solid var(--k-hair);
  display:flex;justify-content:space-between;gap:14px;flex-wrap:wrap;background:var(--k-paper)}
.kb-foot p{margin:0;display:flex;align-items:center}
.kb-foot a{color:var(--k-grey);text-decoration:none;display:inline-flex;align-items:center;
  min-height:44px;padding:2px 0}
.kb-foot a:hover{color:var(--k-ink)}

/* A paragraph with the class nav-label names its section in the index rail.
   It never appears on the page. Edit it to rename a rail entry; delete it and
   the rail falls back to the section heading. */
body.kb-ink-home .nav-label{display:none}

/* ---- scroll life on the bleeding pictures ----
   karla-motes.js sets --sat and --rev per picture as the plate travels through
   the viewport. No geometric mask and no blend mode: both produced a visible
   rectangle, because a blurred box and a multiply layer both have edges the
   artwork does not. The reveal is a scale and a saturation ramp, and the halo
   is a blurred copy of the same picture in normal blending, which follows the
   alpha instead of the bounding box. */
body.kb-ink-home .wp-block-image.kb-live{position:relative}
body.kb-ink-home .wp-block-image.kb-live > img{
  --sat:.6; --rev:.2;
  /* saturate() ONLY. contrast() and brightness() both apply an offset rather
     than a pure colour matrix, and on a cut-out PNG that lifts the fully
     transparent pixels off zero: the artwork's whole bounding box printed as
     a faint grey rectangle on the paper. saturate() is a colour matrix, so it
     follows the alpha exactly and leaves transparent pixels transparent.
     Do not add contrast or brightness back. */
  filter:saturate(var(--sat));
  transform:scale(calc(.945 + var(--rev) * .055));
  transform-origin:50% 60%;
  will-change:filter,transform}

/* No blurred halo layer. A blurred copy of the picture behind it washed a
   visible rectangle across the plate, because a blur has a bounding box the
   artwork does not. The "glow" is carried by the saturation and brightness
   ramp on the picture itself, which follows the alpha exactly. */
body.kb-ink-home .kb-glow{display:none}

/* The two overlay layers are direct children of the plate, so they were being
   caught by the `.plate > *` rule that constrains content to the 1080px
   reading measure. The canvas bitmap was being squeezed from the full section
   width down into 1080px, which is exactly why every round speck was drawn as
   an ellipse. They are overlays, not content, so they opt out. */
body.kb-ink-home .plate > .kb-dust,
body.kb-ink-home .plate > .kb-motes{max-width:none;width:auto;margin:0}

/* the fine particle field, one canvas per picture, drawn in karla-dust.js */
body.kb-ink-home .kb-dust{position:absolute;left:0;top:0;z-index:1;
  pointer-events:none;display:block}
/* no CSS mask here on purpose: the edge fade and the fade away from the
   reading column are both computed per particle in karla-dust.js, because a
   mask on the canvas box left a visible rectangle. */
@media(max-width:900px){ body.kb-ink-home .kb-dust{opacity:.34} }

/* the floating pieces cut from the artwork itself */
/* The layer is anchored to the SECTION, not to the picture. On the picture it
   inherited the picture's soft edge mask, so every piece was sliced at the
   mask line, and because the picture deliberately runs off the side of the
   screen a third of the pieces were placed where nobody could see them. */
body.kb-ink-home .kb-motes{position:absolute;inset:0;z-index:3;pointer-events:none;display:block}
/* The fade away from the reading column is applied per piece in
   karla-motes.js, from each piece's real position against the real column.
   A mask on the layer did not hold once the drift distance went up. */
body.kb-ink-home .kb-mote{position:absolute;left:0;top:0;opacity:0;display:block;
  height:auto !important;max-height:none;
  will-change:transform,opacity;filter:saturate(1.12)}

@media(max-width:900px){
  /* No transform or opacity override here any more: both are computed in
     karla-motes.js now, and clearing the transform would stack every piece in
     the corner of the section. Only the size is forced. */
  body.kb-ink-home .kb-mote{width:11px !important;filter:none !important}
  body.kb-ink-home .kb-glow{display:none}
}
@media(prefers-reduced-motion:reduce){
  body.kb-ink-home .wp-block-image.kb-live img{filter:none;transform:none}
  body.kb-ink-home .kb-glow{opacity:0 !important}
}

/* ---- reveal ---- */
.f{opacity:0;transform:translateY(26px);
  transition:opacity 1.3s cubic-bezier(.16,1,.3,1),transform 1.3s cubic-bezier(.16,1,.3,1)}
.f.vis{opacity:1;transform:none}
.f[data-d="1"]{transition-delay:.16s}
.f[data-d="2"]{transition-delay:.32s}

/* ---- the index rail shares the right gutter with the plates ---- */
@media(min-width:901px){
  /* the rail is fixed in the right gutter, so every plate must reserve it */
  body.kb-ink-home .plate{padding-right:clamp(210px,17vw,290px)}
  .kb-foot{padding-right:clamp(210px,17vw,290px)}
}
@media(max-width:900px){
  .idx{display:none}
  body.kb-ink-home .plate .in.wp-block-columns{grid-template-columns:1fr !important;gap:34px}

  /* Stacked layout is centred: picture, heading and copy all share one axis.
     Left aligned text under a centred picture read as though the two were
     unrelated. */
  body.kb-ink-home .plate,
  body.kb-ink-home .plate .wp-block-column{text-align:center}
  body.kb-ink-home .plate p,
  body.kb-ink-home .plate .lede{margin-left:auto;margin-right:auto}
  body.kb-ink-home .hero .wp-block-column:last-child p{margin-left:auto;margin-right:auto}
  /* display:flex as well as justify-content: the biography portrait's figure
     is a plain block (only the practice plates were given flex), so setting
     the alignment alone did nothing and Karla's portrait stayed left. */
  body.kb-ink-home .plate .wp-block-image{display:flex;justify-content:center}
  body.kb-ink-home .plate .wp-block-image img{margin-left:auto;margin-right:auto}
  body.kb-ink-home .plate .wp-block-table{margin-left:auto;margin-right:auto}
  /* a two column spec table still reads as label on the left, value on the
     right, rather than both crowding the middle */
  body.kb-ink-home .plate table td:first-child,
  body.kb-ink-home .plate table th:first-child{text-align:left}
  body.kb-ink-home .plate table td:last-child,
  body.kb-ink-home .plate table th:last-child{text-align:right}
  /* core makes the button row a flex container, so text-align does not reach
     the button itself */
  body.kb-ink-home .plate .wp-block-buttons{justify-content:center}
  body.kb-ink-home .plate{padding:12vh 22px;min-height:auto}
  .brand{top:22px}
  .motion{bottom:16px;right:16px;border:0;padding:10px 14px;min-height:40px}
  /* The language pair and the motion toggle move into the burger panel on a
     narrow screen. Left fixed in the corners they printed straight over the
     body copy. Repeated here because this sheet loads after style.css and
     the base .lang rule sets display:flex. */
  .lang,
  .motion{display:none}
  /* the biography portrait leads on a narrow screen */
  body.kb-ink-home .b .wp-block-image img{max-width:320px}
}
/* A tablet in portrait is stacked like a phone but has far more room. The
   phone's height cap left the artwork at barely a third of the screen. */
@media(min-width:601px) and (max-width:900px){
  body.kb-ink-home .plate.bleed-r .wp-block-image > img,
  body.kb-ink-home .plate.bleed-l .wp-block-image > img{max-height:62vh}
  body.kb-ink-home .b .wp-block-image img{max-width:400px}
  body.kb-ink-home .plate p{max-width:52ch}
}
/* Short desktop window: the language pair and the pause control are pinned to
   the bottom corners, and on a laptop turned landscape, or with the admin bar
   taking a slice, the last line of a section was running underneath them. */
@media(min-width:901px) and (max-height:820px){
  body.kb-ink-home .plate{padding-top:118px;padding-bottom:9vh}
  /* The rail is centred on the window and the language pair sits above the
     pause control in the same gutter. On a short window the rail grew down
     into them, so it tightens up and shifts clear. */
  .idx a{padding:5px 0;min-height:34px}
  .idx{top:calc(50% - 38px)}
}
@media(prefers-reduced-motion:reduce){
  body.kb-ink-home *{transition-duration:.001ms !important;animation:none !important}
  .f{opacity:1;transform:none}
  html:has(body.kb-ink-home){scroll-behavior:auto}
}

/* admin bar */
body.kb-ink-home.admin-bar .plate{min-height:calc(100svh - 32px)}
body.kb-ink-home.admin-bar .brand{top:62px}
body.kb-ink-home.admin-bar .idx{top:calc(50% + 16px)}
@media screen and (max-width:782px){ body.kb-ink-home.admin-bar .plate{min-height:calc(100svh - 46px)} }
