/* ======================================================================
   solutions/schools.html #teach: the teacher dashboard (bar-k12-ops.md).
   The Universities page's #ops section, copied as-is at the user's request
   (2026-10-01: "이 부분 섹션과 똑같이"): a §5.3 sand panel, a sticky left
   column (pill → heading → line, a live index of the five cards, one CTA)
   and five equal §9.4 cards on the right, each a pastel tile holding one real
   crop of the client's K–12 teacher screens (assets/schools/ops,
   sources in assets/schools/SOURCES.md). Only the names change: .uni-ops →
   .ks-ops, js/uni-ops.js → js/ks-ops.js. Its own file so the K–12 page's
   other sections (css/schools.css) are untouched.
   Scroll-spy: js/ks-ops.js. Without JS the index is plain anchor links.
   ====================================================================== */

.ks-ops {
  margin-inline: var(--sp-8);
  padding-block: var(--sp-56);          /* §5.3 panel padding at every width */
  border-radius: var(--radius--2xl);
  background: var(--color--sand-100);
}
.ks-ops__grid { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--sp-32); }

/* ---- Left column: opener (§5.4), index, CTA. Vertical rhythm lives in
   custom properties so short windows can tighten it (see the sticky block). */
.ks-ops__aside {
  --ops-gap-lede: var(--sp-20);
  --ops-gap-index: var(--sp-24);
  --ops-gap-cta: var(--sp-24);
  --ops-row: 2.52rem;
}
.ks-ops__title {
  margin-top: var(--sp-8);              /* .pill + h2 (§4.3) */
  line-height: var(--lh-tight);         /* §4.1's h2 row: 1.0 (KO: §4.1.2 below) */
  color: var(--forest-ink);             /* client 2026-10-01: this section's type is the ink, not the sand pair */
}
/* Each sentence (EN) / phrase (KO) balances on its own, so a break never strands
   a runt ("Shaped to", "덜어요.") and the two halves stay two halves. */
.ks-ops__phrase { display: block; text-wrap: balance; }
.ks-ops__lede {
  margin-top: var(--ops-gap-lede);
  font-size: var(--fs-body-l);
  line-height: var(--lh-body);
  color: var(--forest-ink);
}

/* The index — Lattice Grow's list, copied at the client's request (2026-10-01:
   "lattice랑 똑같이"): no row fill, muted items with the active one in the
   panel's ink, a 0.72rem ring dot on a 2px rail that fills (sand-400) down to the
   active item (--ops-progress, set by js/ks-ops.js). Measured on lattice.com:
   1.2rem/1.3 text, 0.48rem 0.48rem 0.48rem 0.96rem padding, dot sand-100 with a
   1px sand-200 ring, rail ink at 8%, 0.3s ease. Inactive items are the sand
   midpoint between 600 and 800 (2.9:1, the same contrast as Lattice's #889494) —
   a recorded exception to AA for this list, chosen by the client; the active item
   (sand-1000, 6.15:1), the heading and the CTA carry the section at full contrast. */
.ks-ops__index { margin-top: var(--ops-gap-index); }
.ks-ops__list {
  --ops-dot: 0.72rem;
  position: relative;
  list-style: none;
  margin: 0;
  padding: 0;
}
.ks-ops__list::before,
.ks-ops__list::after {
  content: '';
  position: absolute;
  left: 0;
  top: calc(var(--ops-row) / 2);
  width: 2px;
  height: calc(100% - var(--ops-row));
  background: rgb(0 31 31 / 0.08);
}
.ks-ops__list::after {
  background: var(--color--sand-400);
  transform-origin: top;
  transform: scaleY(var(--ops-progress, 0));
  transition: transform var(--dur) var(--ease-global);
}
.ks-ops__list li { position: relative; z-index: 1; }
.ks-ops .ks-ops__list li a.ks-ops__link {
  /* not an inline link: no §8.5 underline (this selector outweighs styles.css's
     `li a:not(…)` and wins on order) */
  background-image: none;
}
.ks-ops__link {
  position: relative;
  display: flex;
  border-radius: var(--radius--s);      /* §7: the focus ring follows a rounded box */
  /* The box starts one dot-width left of the rail so the focus ring wraps the
     dot instead of cutting it; padding and the dot's offset add the same width
     back, so nothing moves on screen. */
  margin-left: calc(-1 * var(--ops-dot));
  align-items: center;
  min-height: var(--ops-row);
  padding: 0.48rem 0.48rem 0.48rem calc(0.96rem + var(--ops-dot));
  font-size: var(--fs-body-l);
  line-height: var(--lh-body);
  color: color-mix(in srgb, var(--forest-ink) 45%, #fff);   /* the ink, lightened — same Lattice contrast step, now on the black axis */
  transition: color var(--dur) var(--ease-global);
}
.ks-ops__linktext { text-wrap: balance; }
.ks-ops__link:hover,
.ks-ops__link[aria-current='true'] { color: var(--forest-ink); }
.ks-ops__dot {
  position: absolute;
  left: calc(var(--ops-dot) / 2 + 1px);   /* centred on the 2px rail (box starts one dot-width left) */
  top: 50%;
  width: var(--ops-dot);
  height: var(--ops-dot);
  margin-top: calc(var(--ops-dot) / -2);
  border-radius: var(--radius--circle);
  background: var(--color--sand-100);
  box-shadow: inset 0 0 0 1px var(--color--sand-200);
}
.ks-ops__dot::after {
  content: '';
  position: absolute;
  inset: 25%;
  border-radius: var(--radius--circle);
  background: var(--color--sand-200);
  transition: background-color var(--dur) var(--ease-global);
}
.ks-ops__link[aria-current='true'] .ks-ops__dot { box-shadow: inset 0 0 0 1px var(--color--sand-400); }
.ks-ops__link[aria-current='true'] .ks-ops__dot::after { background: var(--color--sand-800); }

.ks-ops__cta { margin-top: var(--ops-gap-cta); }

/* ---- Right column: five equal §9.4 cards ---- */
.ks-ops__cards { display: grid; gap: var(--sp-24); }
.ks-ops__card {
  display: flex;                        /* §9.4: 0.4rem padding and internal gap, overflow hidden */
  flex-direction: column;
  gap: var(--sp-4);
  overflow: hidden;
  padding: var(--sp-4);
  border-radius: var(--radius--l);
  background: #fff;
  box-shadow: var(--shadow--card);
  scroll-margin-top: calc(var(--nav-h) + var(--ops-stick, var(--sp-24)));
}
/* One hue pair per card, from the 100–200 rungs; neighbours never share a family. */
.ks-ops__card[data-hue='meadow'] { --ops-a: var(--color--yellow-100); --ops-b: var(--color--green-200); }
.ks-ops__card[data-hue='sky']    { --ops-a: var(--color--blue-100);   --ops-b: var(--color--purple-200); }
.ks-ops__card[data-hue='peach']  { --ops-a: var(--color--pink-100);   --ops-b: var(--color--yellow-200); }
.ks-ops__card[data-hue='mint']   { --ops-a: var(--color--teal-200);   --ops-b: var(--color--blue-100); }
.ks-ops__card[data-hue='lilac']  { --ops-a: var(--color--violet-100); --ops-b: var(--color--pink-200); }

/* The tile: one box for all five, 1.9:1 at every width, holding one client
   screenshot (.ks-ops__shot, below). */
.ks-ops__tile {
  position: relative;
  margin: 0;
  aspect-ratio: 1.9 / 1;
  overflow: hidden;
  border-radius: var(--radius--m);      /* concentric: 1.2rem card − 0.4rem padding */
  background: linear-gradient(150deg, var(--ops-a) 10%, var(--ops-b) 90%);
}

/* The product shot sits where the redrawn panel used to: the same inset, the
   same §7 radius and §6 rung, running off the tile's bottom edge. Real client
   screenshots (assets/schools/ops), not a redraw — client, 2026-10-01. */
.ks-ops__shot {
  position: absolute;
  left: 11%;
  top: 4.3%;
  width: 78%;
  height: auto;
  display: block;
  border-radius: var(--radius--m);
  box-shadow: var(--shadow--card-large);
}

.ks-ops__body { padding: var(--sp-16) var(--sp-12) var(--sp-12); }
.ks-ops__label {
  font-size: var(--fs-label);           /* §4.1's label row: 0.7rem / 500 */
  font-weight: 500;
  line-height: var(--lh-body);
  color: var(--forest-ink);             /* client 2026-10-01: black type across this section */
}
.ks-ops__h3 {
  margin-top: var(--sp-4);
  font-size: var(--fs-h5);
  font-weight: 500;
  line-height: var(--lh-heading);       /* §4.1's h5 row: 1.2 */
  letter-spacing: var(--kern-heading);
  color: var(--forest-ink);
}
.ks-ops__text {
  margin-top: var(--sp-8);
  font-size: var(--fs-body);
  line-height: var(--lh-body);
  color: var(--forest-ink);
}

/* ---- ≥ 1081: two columns, 45 / 55 (§5.2's asymmetric pair). On the §10.3
   set: at 961 the column (647–670px tall) does not fit a 700–768 window and the
   tiles drop to 454px, so the pair starts above the 1080 breakpoint. ---- */
@media (min-width: 1081px) {
  .ks-ops__grid {
    grid-template-columns: minmax(0, 45fr) minmax(0, 55fr);
    gap: var(--sp-20);
    align-items: start;
  }
  /* Five equal cards beside the sticky column (Lattice's are one size). */
  .ks-ops__cards { grid-template-rows: repeat(5, 1fr) auto; }
}
/* Sticky where the column fits under the nav; js/ks-ops.js measures it and
   adds .is-static if it would still run off the bottom. */
@media (min-width: 1081px) and (min-height: 560px) {
  .ks-ops { --ops-stick: var(--sp-24); }
  .ks-ops__aside {
    position: sticky;
    top: calc(var(--nav-h) + var(--ops-stick));
  }
  .ks-ops__aside.is-static { position: static; }
}
/* Short laptop windows (1280×700, 1280×720, 1081×700): same pieces, tighter. */
@media (min-width: 1081px) and (max-height: 820px) {
  .ks-ops { --ops-stick: var(--sp-16); }
  .ks-ops__aside {
    --ops-gap-lede: var(--sp-12);
    --ops-gap-index: var(--sp-16);
    --ops-gap-cta: var(--sp-16);
    --ops-row: 2rem;
  }
  .ks-ops__link { padding-block: 0.2rem; }
}

/* ---- ≤ 1080: one centred column, in DOM order — opener, index, CTA, cards.
   Capped at 34rem so the cards keep the desktop tile's proportions. ---- */
@media (max-width: 1080.98px) {
  .ks-ops__grid { max-width: calc(34rem + 2 * var(--gutter)); }
}
@media (max-width: 640px) {
  .ks-ops__grid { max-width: calc(26rem + 2 * var(--gutter)); }
  .ks-ops__cta { display: flex; width: 100%; white-space: normal; text-align: center; }
}

/* ---- §4.1.2 Hangul. The section h2 and p already take the page's
   `:lang(ko) .ks-section` rules; add the h3 and the index, and keep the label
   on the Latin row (§4.1.2: labels, tags, buttons stay as the Latin row). ---- */
:lang(ko) .ks-ops__h3 {
  line-height: var(--lh-heading);
  letter-spacing: var(--kern-heading);
  word-break: keep-all;
}
/* The index items are navigation labels — §4.1.2's label row (Latin leading). */
:lang(ko) .ks-ops__link { word-break: keep-all; }
:lang(ko) .ks-section .ks-ops__label { line-height: var(--lh-body); }
