/* ==========================================================================
   software-development.css
   Page-scoped design system for software-development.html
   --------------------------------------------------------------------------
   Namespaced under `.sd-page`. It shares no class name and no layout pattern
   with `.rc-its` (IT Support) or `.rc-itc` (IT Consultancy).

   Register: a technical drawing. Where IT Support is soft navy-and-porcelain
   and IT Consultancy is grained stone-and-brutalism, this page is line work —
   a drafting-slate surface with visible column rules, hairline strokes,
   bracketed frames and schematics that draw themselves. Mass is replaced by
   line; fills are rare and mean something when they appear.

   The brand orange and the two typefaces are the only things all three pages
   have in common.

   Contents
     1. Tokens
     2. Base + typography
     3. Column rules (the drafting grid)
     4. Entrance primitive
     5. Minimap navigation
     6. Hero — blueprint + editor
     7. Branch graph
     8. Route — CSS motion path
     9. Rise — the elevation drawing
    10. Seam — interlocking halves
    11. Migrate — before → after
    12. Brackets
    13. Scale — engagement spectrum
    14. Close — self-closing frame
    15. Responsive
    16. Reduced motion
   ========================================================================== */

/* ==========================================================================
   1. TOKENS
   The surface is a drafting slate: cooler and several steps darker than the
   IT Support porcelain, and grey rather than the warm stone of IT
   Consultancy, so the three pages are never mistaken for each other.
   Nothing here is white; the lightest value on the page is #E4E9EC and it is
   used only for strokes and small fills.
   ========================================================================== */
.sd-page {
  /* Surfaces */
  --sd-paper: #d8dde1; /* drafting slate                              */
  --sd-paper-2: #c9d1d6; /* one step down, alternating sections         */
  --sd-raise: #e4e9ec; /* lifted line work                            */
  --sd-ink: #08131f; /* drawing ink                                 */
  --sd-ink-2: #102436; /* raised surface on ink                       */

  /* Brand — unchanged from the live site */
  --sd-signal: #ee690c;
  --sd-blue: #0c2957;

  /* Text */
  --sd-text: #12202e;
  --sd-text-soft: #4d5b6b;
  --sd-text-inv: #dde5ec;
  --sd-text-inv-s: #93a3b3;

  /* Strokes. Every rule on this page comes from one of these two. */
  --sd-line: rgba(8, 19, 31, 0.17);
  --sd-line-inv: rgba(221, 229, 236, 0.17);
  --sd-rule: rgba(8, 19, 31, 0.11);

  /* Rhythm */
  --sd-space: clamp(72px, 9vw, 136px);
  --sd-gutter: clamp(22px, 3.4vw, 56px);

  --sd-ease: cubic-bezier(0.24, 0.78, 0.24, 1);
  --sd-header: 112px; /* clearance for the site's sticky header      */
}

/* ==========================================================================
   2. BASE + TYPOGRAPHY
   Kanit is used at 300 for display and 500 for line labels — the two earlier
   pages use 600 and 700, so the same family reads as a different voice here.
   ========================================================================== */
body.sd-page {
  background: var(--sd-paper);
  color: var(--sd-text);
}

.sd-page main p {
  font-family: "Montserrat", sans-serif;
  font-size: clamp(15.5px, 1.02vw, 16.5px);
  line-height: 1.8;
  margin: 0 0 1.15em;
  max-width: 64ch;
  text-wrap: pretty;
}
.sd-page main p:last-child {
  margin-bottom: 0;
}

.sd-page .sd-h2 {
  font-family: "Kanit", sans-serif;
  font-weight: 300;
  font-size: clamp(27px, 3.2vw, 48px);
  line-height: 1.08;
  letter-spacing: -0.012em;
  color: var(--sd-text);
  margin: 0 0 0.7em;
  text-wrap: balance;
}
/* A heading carrying a drawn tick at its left — the annotation mark used
   throughout the page, never a number. */
.sd-page .sd-h2--mark {
  position: relative;
  padding-left: 34px;
}
.sd-page .sd-h2--mark::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.52em;
  width: 18px;
  height: 1px;
  background: var(--sd-signal);
}
.sd-page .sd-h2--mark::after {
  content: "";
  position: absolute;
  left: 0;
  top: calc(0.52em - 3px);
  width: 7px;
  height: 7px;
  background: var(--sd-signal);
}
.sd-page .sd-h2--display {
  font-size: clamp(30px, 4vw, 56px);
}

/* The line that introduces the page's single list. A thin rule and a
   heavier weight — structure, not an all-caps label. */
.sd-page .sd-cue {
  font-family: "Kanit", sans-serif;
  font-weight: 500;
  font-size: clamp(16px, 1.35vw, 19px);
  color: var(--sd-text);
  margin-top: 1.5em;
  padding-top: 0.8em;
  border-top: 1px solid var(--sd-ink);
  max-width: none;
}

/* Closing paragraph of a block: centred and narrow, so it reads as a caption
   under the drawing rather than as more body copy. */
.sd-page .sd-tail {
  max-width: 58ch;
  margin: var(--sd-gutter) auto 0;
  text-align: center;
  color: var(--sd-text-soft);
}

.sd-page main ul {
  list-style: none;
  margin: 0;
  padding: 0;
}

.sd-page a:focus-visible,
.sd-page [tabindex]:focus-visible {
  outline: 2px solid var(--sd-signal);
  outline-offset: 4px;
}

/* Section shells. Padding lives on one class only, so modifiers cannot tie
   on specificity and cancel each other out. */
.sd-page .sd-section {
  position: relative;
  padding: var(--sd-space) 0;
  overflow: hidden;
}
.sd-page .sd-section--paper {
  background: var(--sd-paper);
}
.sd-page .sd-section--paper-2 {
  background: var(--sd-paper-2);
}
.sd-page .sd-section--ink {
  background: var(--sd-ink);
  --sd-rule: var(--sd-line-inv);
}
.sd-page .sd-section--ink .sd-h2 {
  color: var(--sd-text-inv);
}
.sd-page .sd-section--ink p {
  color: var(--sd-text-inv);
}

/* PERFORMANCE: rendering is skipped for the two sections that neither pin,
   measure, nor run a scroll-linked transform. It is kept off everything else,
   because skipped content has no layout and a scroll timeline would resolve
   against a zero-height box. */
.sd-page #sd-code,
.sd-page #sd-flexible {
  content-visibility: auto;
  contain-intrinsic-size: auto 800px;
}

/* ==========================================================================
   3. COLUMN RULES — the drafting grid
   A repeating hairline every twelfth of the section width. It is the page's
   signature and its measuring device: the risers in the Scalable section are
   legible as growth only because these rules are there to count against.
   Drawn with one repeating gradient — no elements, no image.
   ========================================================================== */
.sd-page .sd-rules {
  --cols: 12;
  position: absolute;
  inset: 0;
  pointer-events: none;
  background-image: repeating-linear-gradient(
    to right,
    var(--sd-rule) 0 1px,
    transparent 1px calc(100% / var(--cols))
  );
}
.sd-page .sd-rules--strong {
  --sd-rule: rgba(8, 19, 31, 0.2);
}
.sd-page .sd-rules--fine {
  --cols: 24;
}

/* ==========================================================================
   4. ENTRANCE PRIMITIVE
   Used only by blocks with no scroll-driven treatment of their own. On this
   page the entrance is a horizontal slide rather than the vertical lift used
   on the other two — line work is drawn across, not dropped in.
   Gated on `html.sd-js`, so the page reads without JavaScript.
   ========================================================================== */
.sd-js .sd-page [data-in] {
  opacity: 0;
  transform: translate3d(-18px, 0, 0);
  transition:
    opacity 0.75s var(--sd-ease),
    transform 0.75s var(--sd-ease);
  transition-delay: var(--sd-delay, 0ms);
}
.sd-js .sd-page [data-in].is-in {
  opacity: 1;
  transform: none;
}

/* ==========================================================================
   5. MINIMAP NAVIGATION
   A scale drawing of the document: every section is a bar whose height is
   proportional to the section's real height (JS writes --h from the measured
   value), and a cursor line marks the exact reading position. So it answers
   two questions the other two pages' navigation cannot — how long is this
   part, and how far into it am I.
   ========================================================================== */
.sd-page .sd-map {
  position: fixed;
  right: 20px;
  top: 50%;
  z-index: 900;
  transform: translateY(-50%) translateX(200%);
  transition: transform 0.5s var(--sd-ease);
  /* A flat ink strip rather than a translucent panel: the map has to stay
       legible over both the slate and the ink sections. */
  background: rgba(8, 19, 31, 0.62);
  border: 1px solid rgba(221, 229, 236, 0.16);
  padding: 8px 7px;
}
.sd-page .sd-map.is-visible {
  transform: translateY(-50%) translateX(0);
}

.sd-page .sd-map ul {
  display: flex;
  flex-direction: column;
  gap: 4px;
  height: 46vh;
  max-height: 420px;
  margin: 0;
  list-style: none;
}
/* --h is the section's measured height; flex-grow turns it into a
   proportional bar without any absolute positioning. */
.sd-page .sd-map li {
  flex: var(--h, 1) 1 0;
  display: flex;
  min-height: 10px;
}
.sd-page .sd-map a {
  flex: 1;
  display: flex;
  position: relative;
}
.sd-page .sd-map__bar {
  flex: 1;
  width: 6px;
  background: rgba(221, 229, 236, 0.26);
  transition: background 0.3s var(--sd-ease);
}
.sd-page .sd-map a:hover .sd-map__bar {
  background: rgba(221, 229, 236, 0.6);
}
.sd-page .sd-map a.is-current .sd-map__bar {
  background: var(--sd-signal);
}

/* Exact reading position, written by JS as a percentage. */
.sd-page .sd-map__cursor {
  position: absolute;
  left: 2px;
  right: 2px;
  top: 8px;
  height: 1px;
  background: var(--sd-raise);
  pointer-events: none;
  z-index: 2;
}

.sd-page .sd-map__tip {
  position: absolute;
  right: calc(100% + 12px);
  top: 50%;
  transform: translateY(-50%);
  width: max-content;
  max-width: 230px;
  padding: 7px 11px;
  background: var(--sd-raise);
  border: 1px solid var(--sd-ink);
  font-family: "Montserrat", sans-serif;
  font-size: 12px;
  font-weight: 600;
  line-height: 1.3;
  color: var(--sd-text);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.25s var(--sd-ease);
}
.sd-page .sd-map a:hover .sd-map__tip,
.sd-page .sd-map a:focus-visible .sd-map__tip {
  opacity: 1;
}

/* ==========================================================================
   6. HERO — blueprint + editor
   The only dark hero among the service pages: a fine drafting grid on ink,
   the title first, and a code editor that writes itself in on the right.
   ========================================================================== */
.sd-page .sd-hero {
  position: relative;
  background: var(--sd-ink);
  color: var(--sd-text-inv);
  padding: calc(var(--rcnav-clearance, 100px) + clamp(28px, 5vh, 64px)) 0
    clamp(48px, 6vw, 88px);
  overflow: hidden;
  isolation: isolate;
}

/* Blueprint grid: major and minor lines, faded out towards the edges. */
.sd-page .sd-hero__blueprint {
  position: absolute;
  inset: 0;
  z-index: -2;
  pointer-events: none;
  background-image:
    linear-gradient(rgba(221, 229, 236, 0.07) 1px, transparent 1px),
    linear-gradient(90deg, rgba(221, 229, 236, 0.07) 1px, transparent 1px),
    linear-gradient(rgba(221, 229, 236, 0.03) 1px, transparent 1px),
    linear-gradient(90deg, rgba(221, 229, 236, 0.03) 1px, transparent 1px);
  background-size:
    96px 96px,
    96px 96px,
    24px 24px,
    24px 24px;
  -webkit-mask-image: radial-gradient(ellipse 90% 80% at 60% 40%, #000 40%, transparent 100%);
  mask-image: radial-gradient(ellipse 90% 80% at 60% 40%, #000 40%, transparent 100%);
}
.sd-page .sd-hero__glow {
  position: absolute;
  z-index: -1;
  right: -8%;
  top: 8%;
  width: min(760px, 70vw);
  aspect-ratio: 1;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(238, 105, 12, 0.22) 0%, rgba(238, 105, 12, 0) 65%);
  pointer-events: none;
}

.sd-page .sd-hero__top {
  display: grid;
  grid-template-columns: minmax(0, 1.1fr) minmax(0, 0.9fr);
  gap: clamp(32px, 5vw, 80px);
  align-items: center;
  min-height: calc(100vh - var(--rcnav-clearance, 100px) - 200px);
  min-height: calc(100svh - var(--rcnav-clearance, 100px) - 200px);
}

.sd-page .sd-hero__label {
  display: inline-flex;
  align-items: center;
  gap: 12px;
  font-family: "Kanit", sans-serif;
  font-weight: 500;
  font-size: clamp(14px, 1.15vw, 17px);
  color: var(--sd-signal);
  margin: 0 0 clamp(16px, 2.4vh, 26px);
}
.sd-page .sd-hero__tag {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 0.82em;
  font-weight: 600;
  padding: 4px 8px;
  border: 1px solid rgba(238, 105, 12, 0.5);
  border-radius: 4px;
  background: rgba(238, 105, 12, 0.08);
}

.sd-page .sd-hero__title {
  font-family: "Kanit", sans-serif;
  font-weight: 300;
  font-size: clamp(36px, 4.3vw, 66px);
  line-height: 1.06;
  letter-spacing: -0.028em;
  color: #fff;
  margin: 0;
}
.sd-page .sd-hero__title em {
  font-style: normal;
  white-space: nowrap;
  font-weight: 500;
  color: var(--sd-signal);
}
.sd-page .sd-hero__caret {
  display: inline-block;
  width: 0.07em;
  height: 0.82em;
  margin-left: 0.08em;
  vertical-align: -0.04em;
  background: var(--sd-signal);
  animation: sd-blink 1.05s steps(1) infinite;
}
@keyframes sd-blink {
  50% {
    opacity: 0;
  }
}

.sd-page .sd-hero__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 14px 28px;
  margin-top: clamp(26px, 4.5vh, 44px);
}
.sd-page .sd-hero__btn {
  display: inline-flex;
  align-items: center;
  gap: 12px;
  padding: 15px 26px;
  background: var(--sd-signal);
  color: #fff;
  font-family: "Kanit", sans-serif;
  font-weight: 500;
  font-size: 16px;
  border-radius: 4px;
  text-decoration: none;
  transition:
    transform 0.3s var(--sd-ease),
    box-shadow 0.3s var(--sd-ease);
}
.sd-page .sd-hero__btn:hover,
.sd-page .sd-hero__btn:focus-visible {
  color: #fff;
  transform: translateY(-2px);
  box-shadow: 0 10px 28px rgba(238, 105, 12, 0.35);
}
.sd-page .sd-hero__link {
  font-family: "Kanit", sans-serif;
  font-weight: 400;
  font-size: 16px;
  color: var(--sd-text-inv);
  text-decoration: none;
  border-bottom: 1px solid var(--sd-line-inv);
  padding-bottom: 3px;
  transition:
    color 0.3s var(--sd-ease),
    border-color 0.3s var(--sd-ease);
}
.sd-page .sd-hero__link:hover,
.sd-page .sd-hero__link:focus-visible {
  color: var(--sd-signal);
  border-color: var(--sd-signal);
}

/* Editor window */
.sd-page .sd-hero__editor {
  width: 100%;
  max-width: 520px;
  justify-self: end;
  background: rgba(16, 36, 54, 0.82);
  border: 1px solid var(--sd-line-inv);
  border-radius: 10px;
  box-shadow:
    0 30px 80px rgba(0, 0, 0, 0.45),
    0 0 0 1px rgba(0, 0, 0, 0.2);
  -webkit-backdrop-filter: blur(6px);
  backdrop-filter: blur(6px);
  overflow: hidden;
  animation: sd-editor-in 0.8s var(--sd-ease) 0.1s both;
}
@keyframes sd-editor-in {
  from {
    opacity: 0;
    transform: translateY(18px);
  }
}
.sd-page .sd-editor__bar {
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 12px 16px;
  border-bottom: 1px solid var(--sd-line-inv);
  background: rgba(8, 19, 31, 0.5);
}
.sd-page .sd-editor__dots {
  display: flex;
  gap: 7px;
}
.sd-page .sd-editor__dots i {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: rgba(221, 229, 236, 0.22);
}
.sd-page .sd-editor__dots i:first-child {
  background: var(--sd-signal);
}
.sd-page .sd-editor__file {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 12.5px;
  color: var(--sd-text-inv-s);
}

.sd-page .sd-editor__code {
  margin: 0;
  padding: 20px 18px 22px 0;
  list-style: none;
  counter-reset: sd-ln;
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: clamp(12px, 1vw, 14.5px);
  line-height: 1.85;
  color: var(--sd-text-inv);
}
.sd-page .sd-editor__code li {
  counter-increment: sd-ln;
  white-space: pre;
  opacity: 0;
  transform: translateX(-8px);
  animation: sd-line-in 0.45s var(--sd-ease) both;
  animation-delay: calc(0.55s + var(--n) * 0.13s);
}
.sd-page .sd-editor__code li::before {
  content: counter(sd-ln);
  display: inline-block;
  width: 3.2em;
  padding-right: 1.2em;
  text-align: right;
  color: rgba(147, 163, 179, 0.45);
}
@keyframes sd-line-in {
  to {
    opacity: 1;
    transform: none;
  }
}
.sd-page .sd-editor__code .c {
  color: #6f8295;
  font-style: italic;
}
.sd-page .sd-editor__code .k {
  color: var(--sd-signal);
}
.sd-page .sd-editor__code .f {
  color: #8cc8ff;
}
.sd-page .sd-editor__code .p {
  color: #f3c38f;
}
.sd-page .sd-editor__cursor {
  display: inline-block;
  width: 8px;
  height: 1.1em;
  margin-left: 3px;
  vertical-align: -0.2em;
  background: var(--sd-text-inv);
  animation: sd-blink 1.05s steps(1) infinite;
}

.sd-page .sd-editor__status {
  display: flex;
  justify-content: space-between;
  gap: 12px;
  padding: 10px 16px;
  border-top: 1px solid var(--sd-line-inv);
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 12px;
  color: var(--sd-text-inv-s);
  opacity: 0;
  animation: sd-line-in 0.5s var(--sd-ease) 2.1s both;
}
.sd-page .sd-editor__ok {
  color: #7ed9a0;
}

/* Opening paragraphs: a two-column spec under a hairline. */
.sd-page .sd-hero__spec {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: clamp(24px, 4vw, 64px);
  margin-top: clamp(40px, 6vh, 72px);
  padding-top: clamp(26px, 3vw, 40px);
  border-top: 1px solid var(--sd-line-inv);
}
.sd-page .sd-hero__spec p {
  margin: 0;
  max-width: 60ch;
  color: var(--sd-text-inv-s);
}

/* ==========================================================================
   6b. PHOTOGRAPHS — plates on the drawing
   Photos sit on the page like prints clipped to a technical drawing: a
   hairline frame offset from the picture, orange crop-mark corners and a
   monospace label, so they belong to the line-work register.
   ========================================================================== */
.sd-page .sd-photo {
  position: relative;
  margin: 0;
  padding: 10px;
  border: 1px solid var(--sd-line);
  background: var(--sd-raise);
}
.sd-page .sd-photo::before,
.sd-page .sd-photo::after {
  content: "";
  position: absolute;
  width: 22px;
  height: 22px;
  border: 2px solid var(--sd-signal);
  pointer-events: none;
}
.sd-page .sd-photo::before {
  top: -6px;
  left: -6px;
  border-right: 0;
  border-bottom: 0;
}
.sd-page .sd-photo::after {
  right: -6px;
  bottom: -6px;
  border-left: 0;
  border-top: 0;
}
.sd-page .sd-photo img {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 3 / 2;
  object-fit: cover;
  filter: grayscale(0.25) contrast(1.04);
  transition: filter 0.6s var(--sd-ease);
}
.sd-page .sd-photo:hover img {
  filter: none;
}
.sd-page .sd-photo figcaption {
  display: flex;
  align-items: center;
  gap: 10px;
  padding-top: 10px;
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 12px;
  color: var(--sd-text-soft);
}
.sd-page .sd-photo figcaption::before {
  content: "";
  width: 18px;
  height: 1px;
  background: var(--sd-signal);
}

/* Built: the picture fills the space under the heading. */
.sd-page .sd-head__side .sd-h2 {
  margin-bottom: clamp(24px, 3vw, 40px);
}

/* ==========================================================================
   7. BRANCH GRAPH
   One spine, eight branches alternating sides. The spine draws downward on a
   scroll timeline and each branch's connector extends as its node arrives.
   Both are compositor-side: no JS touches this section.
   The base styles outside @supports are the finished state, so a browser
   without scroll timelines gets a complete graph rather than an empty one.
   ========================================================================== */
.sd-page .sd-head {
  display: grid;
  grid-template-columns: minmax(0, 0.85fr) minmax(0, 1.15fr);
  gap: clamp(26px, 4vw, 64px);
  align-items: stretch;
  margin-bottom: clamp(46px, 5.5vw, 84px);
}

.sd-page .sd-branch {
  position: relative;
}
.sd-page .sd-branch__spine {
  position: absolute;
  left: 50%;
  top: 0;
  bottom: 0;
  width: 1px;
  transform: translateX(-50%);
  background: var(--sd-line);
}
.sd-page .sd-branch__spine i {
  display: block;
  width: 100%;
  height: 100%;
  background: var(--sd-signal);
  transform-origin: 50% 0;
}
.sd-page .sd-branch li {
  position: relative;
  display: flex;
  min-height: 92px;
  align-items: center;
}
.sd-page .sd-branch li:nth-child(odd) {
  justify-content: flex-start;
}
.sd-page .sd-branch li:nth-child(even) {
  justify-content: flex-end;
}

/* The node marker sitting on the spine. A diamond, so it never reads as a
   count the way a numbered dot would. */
.sd-page .sd-branch li::after {
  content: "";
  position: absolute;
  left: 50%;
  top: 50%;
  width: 9px;
  height: 9px;
  margin: -5px 0 0 -5px;
  background: var(--sd-paper);
  border: 1.5px solid var(--sd-signal);
  transform: rotate(45deg);
}
.sd-page .sd-branch__wire {
  position: absolute;
  top: 50%;
  width: 64px;
  height: 1px;
  background: var(--sd-signal);
}
.sd-page .sd-branch li:nth-child(odd) .sd-branch__wire {
  right: 50%;
  transform-origin: 100% 50%;
}
.sd-page .sd-branch li:nth-child(even) .sd-branch__wire {
  left: 50%;
  transform-origin: 0 50%;
}

.sd-page .sd-branch__node {
  width: calc(50% - 72px);
  padding: 18px 22px;
  background: var(--sd-raise);
  border: 1px solid var(--sd-line);
  font-family: "Kanit", sans-serif;
  font-weight: 500;
  font-size: clamp(15px, 1.3vw, 19px);
  line-height: 1.28;
  color: var(--sd-text);
  transition:
    border-color 0.3s var(--sd-ease),
    transform 0.3s var(--sd-ease);
}
.sd-page .sd-branch li:nth-child(odd) .sd-branch__node {
  text-align: right;
}
.sd-page .sd-branch li:hover .sd-branch__node {
  border-color: var(--sd-signal);
}
.sd-page .sd-branch li:nth-child(odd):hover .sd-branch__node {
  transform: translateX(-6px);
}
.sd-page .sd-branch li:nth-child(even):hover .sd-branch__node {
  transform: translateX(6px);
}

@supports (animation-timeline: view()) {
  .sd-page .sd-branch__spine i {
    transform: scaleY(0);
    animation: sd-grow linear both;
    animation-timeline: view();
    animation-range: cover 12% cover 86%;
  }
  @keyframes sd-grow {
    to {
      transform: scaleY(1);
    }
  }

  .sd-page .sd-branch__wire {
    transform: scaleX(0);
    animation: sd-extend linear both;
    animation-timeline: view();
    /* Extends while the branch is entering the viewport, so the connector
           is complete by the time the label is comfortably readable. */
    animation-range: entry 45% entry 100%;
  }
  @keyframes sd-extend {
    to {
      transform: scaleX(1);
    }
  }
}

/* ==========================================================================
   8. ROUTE — CSS motion path
   One drawn frame holds the three stages. A marker travels around the
   frame's own border using `offset-path: border-box`, scrubbed by scroll.
   Because the path is the element's box rather than hard-coded coordinates,
   it reflows correctly at any width. Where motion paths are unsupported the
   marker is hidden — it is decorative, and the stages read without it.
   ========================================================================== */
.sd-page .sd-route {
  position: relative;
  border: 1px solid var(--sd-line-inv);
  padding: clamp(26px, 3.2vw, 54px);
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(22px, 2.6vw, 44px);
  margin-top: clamp(36px, 4vw, 60px);
}
.sd-page .sd-route__stage {
  border-left: 1px solid var(--sd-signal);
  padding-left: clamp(16px, 1.8vw, 26px);
}
.sd-page .sd-route__stage p {
  max-width: none;
  font-size: clamp(14.5px, 1vw, 16px);
}

.sd-page .sd-route__marker {
  display: none;
}
@supports (offset-path: border-box) {
  .sd-page .sd-route__marker {
    display: block;
    position: absolute;
    width: 11px;
    height: 11px;
    background: var(--sd-signal);
    offset-path: border-box;
    offset-distance: 0%;
    offset-rotate: 0deg; /* keep it a square tick, not a tumbling chip */
    animation: sd-travel linear both;
    animation-timeline: view();
    animation-range: cover 0% cover 100%;
  }
  @keyframes sd-travel {
    to {
      offset-distance: 100%;
    }
  }
}

/* ==========================================================================
   9. RISE — the elevation drawing
   Growth is drawn, not described. Three risers of increasing height stand on
   one baseline that runs the full width of the container, measured against a
   dashed guide at full height. The copy sits above its own riser, so the
   argument and the drawing share a column. Risers build up from the baseline
   when the step enters the viewport — the same `is-in` hook the brackets use,
   so it needs no scroll timeline and behaves the same in every browser.
   ========================================================================== */
.sd-page .sd-rise__head {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 0.78fr);
  gap: var(--sd-gutter);
  align-items: end;
}
.sd-page .sd-rise__head .sd-h2 {
  margin-bottom: 0;
}
/* The lead sits at the heading's baseline in Kanit, so it reads as part of
   the title block rather than as the first of the three stages. */
.sd-page .sd-rise__lead {
  font-family: "Kanit", sans-serif;
  font-weight: 300;
  font-size: clamp(17px, 1.6vw, 23px);
  line-height: 1.46;
  color: var(--sd-text-soft);
  max-width: none;
  padding-bottom: 0.35em;
}

.sd-page .sd-rise__steps {
  --rise-dia: clamp(104px, 11.5vw, 196px);
  position: relative;
  list-style: none;
  margin: clamp(46px, 5.5vw, 84px) 0 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(20px, 2.4vw, 40px);
  align-items: stretch;
}
/* The baseline every riser stands on: one line across all three columns, so
   the heights are comparable rather than three separate diagrams. */
.sd-page .sd-rise__steps::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 1px;
  background: var(--sd-ink);
}
/* The guide the tallest riser is measured up to. */
.sd-page .sd-rise__steps::before {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: var(--rise-dia);
  height: 1px;
  background: repeating-linear-gradient(
    to right,
    var(--sd-line) 0 6px,
    transparent 6px 12px
  );
}

.sd-page .sd-rise__step {
  position: relative;
  display: grid;
  grid-template-rows: auto 1fr var(--rise-dia);
  margin: 0;
}
.sd-page .sd-rise__label {
  position: relative;
  font-family: "Kanit", sans-serif;
  font-weight: 500;
  font-size: clamp(16px, 1.35vw, 19px);
  line-height: 1.3;
  color: var(--sd-text);
  margin: 0 0 0.85em;
  padding-top: 18px;
  border-top: 1px solid var(--sd-ink);
}
/* The page's annotation mark, on the step's own rule. */
.sd-page .sd-rise__label::before {
  content: "";
  position: absolute;
  left: 0;
  top: -4px;
  width: 7px;
  height: 7px;
  background: var(--sd-signal);
}
.sd-page .sd-rise__step p {
  max-width: none;
  font-size: clamp(14.5px, 1vw, 16px);
  margin: 0;
  padding-right: clamp(0px, 1.6vw, 26px);
  padding-bottom: clamp(20px, 2.4vw, 36px);
}

/* The riser itself: a hairline column standing on the baseline, capped by a
   solid ink line at its height. The last one is capped in signal, because it
   is the one the dashed guide is drawn for. */
.sd-page .sd-rise__riser {
  align-self: end;
  height: calc(var(--rise-dia) * var(--lift, 0.5));
  border: 1px solid var(--sd-line);
  border-bottom: 0;
  border-top: 2px solid var(--sd-ink);
  background: linear-gradient(
    to top,
    rgba(8, 19, 31, 0.1),
    rgba(8, 19, 31, 0.015)
  );
  transform-origin: 50% 100%;
}
.sd-page .sd-rise__step--peak .sd-rise__riser {
  border-top-color: var(--sd-signal);
  background: linear-gradient(
    to top,
    rgba(238, 105, 12, 0.16),
    rgba(238, 105, 12, 0.02)
  );
}

/* Built from the baseline up, once, when the step arrives. */
.sd-js .sd-page .sd-rise__riser {
  transform: scaleY(0);
  transition: transform 0.85s var(--sd-ease);
  transition-delay: calc(var(--sd-delay, 0ms) + 120ms);
}
.sd-js .sd-page .sd-rise__step.is-in .sd-rise__riser {
  transform: scaleY(1);
}

/* ==========================================================================
   10. SEAM — interlocking halves
   Two systems meeting: an ink half with a notched edge against the slate
   background, copy on either side of the join.
   The ink half is drawn by the LEFT COLUMN'S pseudo-elements, not by a
   layer sized in % of the section. The columns live in a max-width
   container, so a section-relative seam drifted into the right-hand copy on
   wide screens. Anchored to the column, the seam always sits in the middle
   of the grid gap:
     ::before  the solid body, bleeding to the viewport's left edge
     ::after   a 36px strip of teeth (an SVG mask repeated vertically, so
               the teeth keep one size whatever the section height)
   Both bleed far above and below; the section's overflow: hidden trims
   them to its own box. On scroll the ink half slides the last 40px into
   place, driven by the section's named view timeline.
   ========================================================================== */
.sd-page .sd-seam {
  background:
    linear-gradient(290deg, rgba(12, 41, 87, 0.08), transparent 45%),
    var(--sd-paper);
  view-timeline-name: --sd-seam;
}
.sd-page .sd-seam__grid {
  --seam-gap: clamp(30px, 5vw, 90px);
  --seam-teeth: 36px;
  position: relative;
  z-index: 1;
  display: grid;
  grid-template-columns: minmax(0, 1.05fr) minmax(0, 0.95fr);
  gap: var(--seam-gap);
  align-items: center;
}
.sd-page .sd-seam__side--a {
  position: relative;
  isolation: isolate;
  color: var(--sd-text-inv);
  padding-right: clamp(10px, 3vw, 46px);
}
.sd-page .sd-seam__side--a::before,
.sd-page .sd-seam__side--a::after {
  content: "";
  position: absolute;
  z-index: -1;
  top: -150vh;
  bottom: -150vh;
  background: var(--sd-ink);
  pointer-events: none;
}
/* Body: from far off-screen left up to where the teeth begin (plus 1px of
   overlap, so no hairline shows between the two at fractional widths). */
.sd-page .sd-seam__side--a::before {
  left: -100vw;
  right: calc(var(--seam-teeth) - var(--seam-gap) / 2 - 1px);
}
/* Teeth: the last 36px before the middle of the gap. */
.sd-page .sd-seam__side--a::after {
  right: calc(var(--seam-gap) / -2);
  width: var(--seam-teeth);
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='36' height='72'%3E%3Cpolygon points='0,0 36,0 0,36 36,72 0,72'/%3E%3C/svg%3E") 0 0 / 100% 72px repeat-y;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='36' height='72'%3E%3Cpolygon points='0,0 36,0 0,36 36,72 0,72'/%3E%3C/svg%3E") 0 0 / 100% 72px repeat-y;
}
.sd-page .sd-seam__side--a .sd-h2 {
  color: var(--sd-text-inv);
}
.sd-page .sd-seam__side--a p {
  color: var(--sd-text-inv);
}
.sd-page .sd-seam__side--b p {
  font-family: "Kanit", sans-serif;
  font-weight: 300;
  font-size: clamp(17px, 1.6vw, 23px);
  line-height: 1.46;
  color: var(--sd-text);
  max-width: none;
}

@supports (animation-timeline: view()) {
  .sd-page .sd-seam__side--a::before,
  .sd-page .sd-seam__side--a::after {
    animation: sd-mesh linear both;
    animation-timeline: --sd-seam;
    animation-range: cover 0% cover 62%;
  }
  @keyframes sd-mesh {
    from {
      transform: translateX(-40px);
    }
    to {
      transform: translateX(0);
    }
  }
}

/* ==========================================================================
   11. MIGRATE — before → after
   An asymmetric comparison: the legacy system as a hatched, dashed drawing
   of something obsolete, the modernised platform as a solid ink panel, and
   a flowing arrow between them. Unlike the equal three-up rows elsewhere on
   the page, the two sides differ in width, weight and colour on purpose.
   ========================================================================== */
.sd-page .sd-migrate__head {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  justify-content: space-between;
  gap: 18px 40px;
  margin-bottom: clamp(34px, 4vw, 60px);
}
.sd-page .sd-migrate__head .sd-h2 {
  margin: 0;
}

/* v1.0 ─── v2.0 version marker */
.sd-page .sd-migrate__ver {
  display: flex;
  align-items: center;
  gap: 12px;
  margin: 0 0 0.4em;
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 13px;
}
.sd-page .sd-migrate__v-old {
  color: var(--sd-text-soft);
  text-decoration: line-through;
  opacity: 0.7;
}
.sd-page .sd-migrate__ver i {
  width: clamp(40px, 6vw, 90px);
  height: 1px;
  background: var(--sd-ink);
  position: relative;
}
.sd-page .sd-migrate__ver i::after {
  content: "";
  position: absolute;
  right: -1px;
  top: -3px;
  border: 3.5px solid transparent;
  border-left: 6px solid var(--sd-ink);
  border-right: 0;
}
.sd-page .sd-migrate__v-new {
  padding: 4px 10px;
  border-radius: 999px;
  background: var(--sd-signal);
  color: #fff;
  font-weight: 600;
}

.sd-page .sd-migrate {
  display: grid;
  grid-template-columns: minmax(0, 5fr) clamp(56px, 6vw, 96px) minmax(0, 6fr);
  align-items: stretch;
}

.sd-page .sd-migrate__card {
  position: relative;
  display: flex;
  flex-direction: column;
  padding: clamp(24px, 2.6vw, 40px);
}
.sd-page .sd-migrate__card p {
  max-width: none;
  font-size: clamp(14.5px, 1vw, 16px);
}

.sd-page .sd-migrate__bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: clamp(18px, 2vw, 26px);
  padding-bottom: 14px;
  border-bottom: 1px solid var(--sd-line);
}
.sd-page .sd-migrate__tag {
  font-family: "Kanit", sans-serif;
  font-weight: 500;
  font-size: 13px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}
.sd-page .sd-migrate__file {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 12px;
}

.sd-page .sd-migrate__chips {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin: auto 0 0;
  padding: clamp(18px, 2vw, 26px) 0 0;
  list-style: none;
}
.sd-page .sd-migrate__chips li {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 5px 11px;
  border-radius: 999px;
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 12px;
}

/* Before: hatched and dashed, drawn in pencil */
.sd-page .sd-migrate__card--before {
  border: 1px dashed rgba(8, 19, 31, 0.35);
  background:
    repeating-linear-gradient(
      -45deg,
      rgba(8, 19, 31, 0.045) 0 1px,
      transparent 1px 9px
    ),
    var(--sd-paper-2);
}
.sd-page .sd-migrate__card--before p {
  color: var(--sd-text-soft);
}
.sd-page .sd-migrate__card--before .sd-migrate__tag {
  color: var(--sd-text-soft);
}
.sd-page .sd-migrate__card--before .sd-migrate__file {
  color: var(--sd-text-soft);
  text-decoration: line-through;
}
.sd-page .sd-migrate__card--before .sd-migrate__chips li {
  border: 1px solid rgba(8, 19, 31, 0.25);
  color: var(--sd-text-soft);
}
.sd-page .sd-migrate__card--before .sd-migrate__chips li::before {
  content: "!";
  display: inline-grid;
  place-items: center;
  width: 15px;
  height: 15px;
  border-radius: 50%;
  background: rgba(8, 19, 31, 0.14);
  font-family: "Kanit", sans-serif;
  font-weight: 700;
  font-size: 11px;
  line-height: 1;
}

/* After: solid ink, orange top rule */
.sd-page .sd-migrate__card--after {
  background: var(--sd-ink);
  color: var(--sd-text-inv);
  border-top: 3px solid var(--sd-signal);
  box-shadow: 0 30px 60px rgba(8, 19, 31, 0.25);
}
.sd-page .sd-migrate__card--after .sd-migrate__bar {
  border-bottom-color: var(--sd-line-inv);
}
.sd-page .sd-migrate__card--after .sd-migrate__tag {
  color: var(--sd-signal);
}
.sd-page .sd-migrate__card--after .sd-migrate__file {
  color: var(--sd-text-inv-s);
}
.sd-page .sd-migrate__card--after p {
  color: var(--sd-text-inv);
}
.sd-page .sd-migrate__card--after p + p {
  padding-top: 1.15em;
  border-top: 1px solid var(--sd-line-inv);
}
.sd-page .sd-migrate__card--after .sd-migrate__chips li {
  border: 1px solid rgba(238, 105, 12, 0.45);
  background: rgba(238, 105, 12, 0.08);
  color: var(--sd-text-inv);
}
.sd-page .sd-migrate__card--after .sd-migrate__chips li::before {
  content: "\2713";
  color: var(--sd-signal);
  font-weight: 700;
}

/* The flow between them: dashes travelling towards the new system */
.sd-page .sd-migrate__flow {
  display: flex;
  align-items: center;
  padding: 0 10px;
}
.sd-page .sd-migrate__flow span {
  position: relative;
  flex: 1;
  height: 2px;
  background: repeating-linear-gradient(
    90deg,
    var(--sd-signal) 0 8px,
    transparent 8px 14px
  );
  background-size: 14px 2px;
  animation: sd-flow 0.9s linear infinite;
}
.sd-page .sd-migrate__flow span::after {
  content: "";
  position: absolute;
  right: -2px;
  top: 50%;
  transform: translateY(-50%);
  border: 7px solid transparent;
  border-left: 11px solid var(--sd-signal);
  border-right: 0;
}
@keyframes sd-flow {
  to {
    background-position: 14px 0;
  }
}

/* ==========================================================================
   12. BRACKETS
   Two crop-mark corners that close around each paragraph as it is reached —
   the visual language of a reviewed, bounded artefact. Driven by a class on
   the parent and a transition on the pseudo-elements, so it behaves
   identically in every browser without needing a scroll timeline.
   This is the still section: once the corners close, nothing moves.
   ========================================================================== */
.sd-page .sd-guard__set {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(20px, 2.4vw, 40px);
  margin-top: clamp(34px, 4vw, 58px);
}
.sd-page .sd-bracket {
  position: relative;
  padding: clamp(26px, 3vw, 42px);
}
.sd-page .sd-bracket::before,
.sd-page .sd-bracket::after {
  content: "";
  position: absolute;
  width: 34px;
  height: 34px;
  border: 1px solid var(--sd-signal);
}
.sd-page .sd-bracket::before {
  top: 0;
  left: 0;
  border-right: 0;
  border-bottom: 0;
  transform-origin: 0 0;
}
.sd-page .sd-bracket::after {
  bottom: 0;
  right: 0;
  border-left: 0;
  border-top: 0;
  transform-origin: 100% 100%;
}
.sd-page .sd-bracket p {
  font-size: clamp(14.5px, 1vw, 16px);
  max-width: none;
}

.sd-js .sd-page .sd-bracket::before,
.sd-js .sd-page .sd-bracket::after {
  transform: scale(0);
  transition: transform 0.7s var(--sd-ease) 0.1s;
}
.sd-js .sd-page .sd-bracket.is-in::before,
.sd-js .sd-page .sd-bracket.is-in::after {
  transform: scale(1);
}

/* ==========================================================================
   13. SCALE — engagement spectrum
   Flexibility drawn as a measuring scale: a track from "extra expertise" to
   "full partner", three engagement stops on it and a marker that slides
   between them. The opening paragraph sits beside it as a lead; the
   conclusion runs underneath at display size as the section's takeaway.
   ========================================================================== */
.sd-page .sd-scale-wrap {
  display: grid;
  grid-template-columns: minmax(0, 6fr) minmax(0, 6fr);
  gap: clamp(32px, 5vw, 80px);
  align-items: start;
}
.sd-page .sd-scale-wrap__lead p {
  font-size: clamp(16.5px, 1.25vw, 19px);
  line-height: 1.7;
  color: var(--sd-text);
}

.sd-page .sd-scale {
  padding: clamp(24px, 2.8vw, 40px);
  background: var(--sd-raise);
  border: 1px solid var(--sd-line);
  box-shadow: 0 24px 50px rgba(8, 19, 31, 0.1);
}
.sd-page .sd-scale__ends {
  display: flex;
  justify-content: space-between;
  gap: 16px;
  margin-bottom: 14px;
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 12px;
  color: var(--sd-text-soft);
}

.sd-page .sd-scale__track {
  position: relative;
  z-index: 1; /* marker passes over the stop dots */
  height: 6px;
  border-radius: 999px;
  background: linear-gradient(90deg, rgba(8, 19, 31, 0.14), var(--sd-signal));
}
/* The marker glides between the three stops and back. */
.sd-page .sd-scale__marker {
  position: absolute;
  top: 50%;
  left: 16.67%;
  width: 22px;
  height: 22px;
  margin: -11px 0 0 -11px;
  border-radius: 50%;
  background: var(--sd-ink);
  border: 3px solid var(--sd-signal);
  box-shadow: 0 0 0 6px rgba(238, 105, 12, 0.16);
  animation: sd-scale-slide 7s var(--sd-ease) infinite;
}
@keyframes sd-scale-slide {
  0%,
  18% {
    left: 16.67%;
  }
  33%,
  51% {
    left: 50%;
  }
  66%,
  84% {
    left: 83.33%;
  }
  100% {
    left: 16.67%;
  }
}

.sd-page .sd-scale__stops {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  margin: 0;
  padding: 0;
  list-style: none;
}
.sd-page .sd-scale__stops li {
  position: relative;
  padding-top: 30px;
  text-align: center;
  font-family: "Kanit", sans-serif;
  font-weight: 500;
  font-size: clamp(13px, 1vw, 15px);
  line-height: 1.25;
  color: var(--sd-text);
}
/* Tick from the track down to each label */
.sd-page .sd-scale__stops li::before {
  content: "";
  position: absolute;
  top: -9px;
  left: 50%;
  width: 12px;
  height: 12px;
  margin-left: -6px;
  border-radius: 50%;
  background: var(--sd-raise);
  border: 2px solid var(--sd-ink);
}
.sd-page .sd-scale__stops li::after {
  content: "";
  position: absolute;
  top: 5px;
  left: 50%;
  width: 1px;
  height: 16px;
  background: var(--sd-line);
}

.sd-page .sd-scale__body {
  margin-top: clamp(26px, 3vw, 38px);
  padding-top: clamp(22px, 2.4vw, 30px);
  border-top: 1px solid var(--sd-line);
}
.sd-page .sd-scale__body p {
  max-width: none;
  color: var(--sd-text-soft);
}

/* The takeaway, at display size under a full-width rule */
.sd-page .sd-scale-result {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  gap: clamp(16px, 2vw, 32px);
  align-items: start;
  margin-top: clamp(48px, 6vw, 88px);
  padding-top: clamp(28px, 3vw, 44px);
  border-top: 1px solid var(--sd-ink);
}
.sd-page .sd-scale-result__mark {
  font-family: "Kanit", sans-serif;
  font-weight: 300;
  font-size: clamp(34px, 3.4vw, 54px);
  line-height: 1;
  color: var(--sd-signal);
}
.sd-page .sd-scale-result p {
  max-width: 34ch;
  margin: 0;
  font-family: "Kanit", sans-serif;
  font-weight: 300;
  font-size: clamp(22px, 2.3vw, 36px);
  line-height: 1.3;
  letter-spacing: -0.01em;
  color: var(--sd-text);
}

/* ==========================================================================
   14. CLOSE — self-closing frame
   The rectangle the hero schematic started is finished here: it strokes
   itself shut around the closing copy. The CTA is an outline button whose
   fill sweeps in from the left — precision rather than the soft pill of the
   IT Support page or the block button of IT Consultancy.
   ========================================================================== */
.sd-page .sd-close {
  background: var(--sd-ink);
}
.sd-page .sd-close__frame {
  position: relative;
  padding: clamp(34px, 4.6vw, 78px);
  max-width: 1000px;
}
.sd-page .sd-close__draw {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
}
.sd-page .sd-close__draw rect {
  fill: none;
  stroke: var(--sd-signal);
  stroke-width: 1.5;
  vector-effect: non-scaling-stroke;
  stroke-dasharray: 1;
  stroke-dashoffset: 0; /* pathLength="1" is set in the markup */
}
/* The undrawn start state exists only when JS is present to finish it —
   otherwise the frame would stay permanently invisible. */
.sd-js .sd-page .sd-close__draw rect {
  stroke-dashoffset: 1;
  transition: stroke-dashoffset 1.8s var(--sd-ease);
}
.sd-js .sd-page .sd-close__frame.is-in .sd-close__draw rect {
  stroke-dashoffset: 0;
}

.sd-page .sd-close__inner {
  position: relative;
  z-index: 1;
  max-width: 860px;
}
.sd-page .sd-close__inner p {
  max-width: none;
}
.sd-page .sd-close__inner .sd-h2 {
  color: var(--sd-text-inv);
}
.sd-page .sd-close__inner p {
  color: var(--sd-text-inv);
}
.sd-page .sd-close__ask {
  font-family: "Kanit", sans-serif;
  font-weight: 300;
  font-size: clamp(18px, 1.7vw, 25px);
  line-height: 1.45;
  border-top: 1px solid var(--sd-line-inv);
  padding-top: 1.1em;
  margin-top: 1.4em;
}
.sd-page .sd-close__cta {
  margin-top: 34px;
}

.sd-page .sd-btn {
  position: relative;
  isolation: isolate;
  display: inline-flex;
  align-items: center;
  gap: 14px;
  padding: 16px 30px;
  border: 1px solid var(--sd-signal);
  color: var(--sd-signal);
  font-family: "Kanit", sans-serif;
  font-weight: 500;
  font-size: clamp(15px, 1.15vw, 17px);
  text-decoration: none;
  transition: color 0.35s var(--sd-ease);
}
.sd-page .sd-btn::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: var(--sd-signal);
  transform: scaleX(0);
  transform-origin: 0 50%;
  transition: transform 0.45s var(--sd-ease);
}
.sd-page .sd-btn:hover {
  color: var(--sd-ink);
}
.sd-page .sd-btn:hover::before {
  transform: scaleX(1);
}
.sd-page .sd-btn i {
  transition: transform 0.45s var(--sd-ease);
}
.sd-page .sd-btn:hover i {
  transform: translateX(7px);
}

/* ==========================================================================
   15. RESPONSIVE
   ========================================================================== */
@media (max-width: 1199.98px) {
  .sd-page .sd-map {
    display: none;
  } /* no free gutter to sit in */
  .sd-page .sd-route,
  .sd-page .sd-guard__set {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (max-width: 991.98px) {
  .sd-page {
    --sd-header: 86px;
  }

  /* The hero stacks: title and actions first, the editor under them,
       then the spec in a single column. */
  .sd-page .sd-hero__top {
    grid-template-columns: 1fr;
    min-height: 0;
  }
  .sd-page .sd-hero__editor {
    justify-self: start;
    max-width: 560px;
  }
  .sd-page .sd-hero__spec {
    grid-template-columns: 1fr;
    gap: 1.15em;
  }

  .sd-page .sd-head {
    grid-template-columns: 1fr;
  }

  /* The spine moves to the left edge and every branch hangs off the same
       side: a centred graph needs width it no longer has. */
  .sd-page .sd-branch__spine {
    left: 6px;
    transform: none;
  }
  .sd-page .sd-branch li,
  .sd-page .sd-branch li:nth-child(odd),
  .sd-page .sd-branch li:nth-child(even) {
    justify-content: flex-end;
    min-height: 0;
    padding: 7px 0;
  }
  .sd-page .sd-branch li::after {
    left: 6px;
  }
  .sd-page .sd-branch li:nth-child(odd) .sd-branch__wire,
  .sd-page .sd-branch li:nth-child(even) .sd-branch__wire {
    left: 6px;
    right: auto;
    width: 36px;
    transform-origin: 0 50%;
  }
  .sd-page .sd-branch__node,
  .sd-page .sd-branch li:nth-child(odd) .sd-branch__node {
    width: calc(100% - 48px);
    text-align: left;
  }

  .sd-page .sd-route,
  .sd-page .sd-guard__set {
    grid-template-columns: 1fr;
  }

  /* Before and after stack; the flow arrow turns to point down. */
  .sd-page .sd-migrate {
    grid-template-columns: 1fr;
  }
  .sd-page .sd-migrate__flow {
    justify-content: center;
    height: 64px;
    padding: 10px 0;
  }
  .sd-page .sd-migrate__flow span {
    flex: none;
    width: 2px;
    height: 100%;
    background: repeating-linear-gradient(
      180deg,
      var(--sd-signal) 0 8px,
      transparent 8px 14px
    );
    background-size: 2px 14px;
    animation-name: sd-flow-down;
  }
  .sd-page .sd-migrate__flow span::after {
    right: auto;
    top: auto;
    left: 50%;
    bottom: -2px;
    transform: translateX(-50%);
    border: 7px solid transparent;
    border-top: 11px solid var(--sd-signal);
    border-bottom: 0;
  }
  @keyframes sd-flow-down {
    to {
      background-position: 0 14px;
    }
  }

  /* Stacked, the risers lose their shared baseline, so the drawing turns on
     its side: each step keeps its copy and lays its riser out as a measured
     bar under it, still against the column rules. */
  .sd-page .sd-rise__head {
    grid-template-columns: 1fr;
    align-items: start;
  }
  .sd-page .sd-rise__lead {
    padding-bottom: 0;
  }
  .sd-page .sd-rise__steps {
    grid-template-columns: 1fr;
    gap: clamp(26px, 4vw, 40px);
  }
  .sd-page .sd-rise__steps::before,
  .sd-page .sd-rise__steps::after {
    display: none;
  }
  .sd-page .sd-rise__step {
    grid-template-rows: auto auto auto;
  }
  .sd-page .sd-rise__step p {
    padding-right: 0;
  }
  .sd-page .sd-rise__step p {
    padding-bottom: clamp(14px, 2vw, 20px);
  }
  .sd-page .sd-rise__riser {
    height: 14px;
    width: calc(100% * var(--lift, 0.5));
    border: 1px solid var(--sd-line);
    border-right: 0;
    border-top: 1px solid var(--sd-line);
    border-left: 2px solid var(--sd-ink);
    background: linear-gradient(
      to right,
      rgba(8, 19, 31, 0.24),
      rgba(8, 19, 31, 0.05)
    );
    transform-origin: 0 50%;
  }
  .sd-page .sd-rise__step--peak .sd-rise__riser {
    border-left-color: var(--sd-signal);
    background: linear-gradient(
      to right,
      rgba(238, 105, 12, 0.34),
      rgba(238, 105, 12, 0.05)
    );
  }
  .sd-js .sd-page .sd-rise__riser {
    transform: scaleX(0);
  }
  .sd-js .sd-page .sd-rise__step.is-in .sd-rise__riser {
    transform: scaleX(1);
  }

  /* The notched seam needs two side-by-side halves to mean anything; on one
       column the ink half becomes a plain block behind the first side. */
  .sd-page .sd-seam__side--a::before,
  .sd-page .sd-seam__side--a::after {
    display: none;
  }
  .sd-page .sd-seam__grid {
    grid-template-columns: 1fr;
  }
  .sd-page .sd-seam__side--a {
    background: var(--sd-ink);
    padding: clamp(24px, 4vw, 40px);
    padding-right: clamp(24px, 4vw, 40px);
  }

  .sd-page .sd-scale-wrap {
    grid-template-columns: 1fr;
  }
}

@media (max-width: 575.98px) {
  .sd-page .sd-rules {
    --cols: 6;
  }
  .sd-page .sd-close__frame {
    padding: 26px 22px;
  }
}

/* Hover affordances are pointer-only: on touch they either never fire or
   stick after a tap. */
@media (hover: none) {
  .sd-page .sd-branch li:hover .sd-branch__node {
    border-color: var(--sd-line);
    transform: none;
  }
}

/* ==========================================================================
   16. REDUCED MOTION
   Every scroll-driven and load-time animation is pinned to its finished
   state. Nothing that carries meaning disappears: the schematic is drawn,
   the spine is full, the plates are flat, the brackets are closed.
   ========================================================================== */
@media (prefers-reduced-motion: reduce) {
  .sd-js .sd-page [data-in] {
    opacity: 1 !important;
    transform: none !important;
    transition: none !important;
  }
  .sd-page .sd-hero__editor,
  .sd-page .sd-editor__code li,
  .sd-page .sd-editor__status {
    animation: none !important;
    opacity: 1 !important;
    transform: none !important;
  }
  .sd-page .sd-hero__caret,
  .sd-page .sd-editor__cursor {
    animation: none !important;
  }
  .sd-page .sd-branch__spine i {
    animation: none !important;
    transform: scaleY(1) !important;
  }
  .sd-page .sd-branch__wire {
    animation: none !important;
    transform: scaleX(1) !important;
  }
  .sd-page .sd-route__marker {
    display: none !important;
  }
  .sd-page .sd-seam__side--a::before,
  .sd-page .sd-seam__side--a::after {
    animation: none !important;
    transform: none !important;
  }
  .sd-page .sd-scale__marker {
    animation: none !important;
    left: 50% !important;
  }
  .sd-page .sd-migrate__flow span {
    animation: none !important;
  }
  .sd-js .sd-page .sd-bracket::before,
  .sd-js .sd-page .sd-bracket::after {
    transform: scale(1) !important;
    transition: none !important;
  }
  .sd-js .sd-page .sd-rise__riser {
    transform: none !important;
    transition: none !important;
  }
  .sd-page .sd-close__draw rect {
    stroke-dashoffset: 0 !important;
    transition: none !important;
  }
  .sd-page *,
  .sd-page *::before,
  .sd-page *::after {
    transition-duration: 0.001ms !important;
  }
}

/* "Our software development services can support:" introduces the branch
   list, so it sits at the foot of the head row, just above the list. */
.sd-page .sd-head__body {
  display: flex;
  flex-direction: column;
}
.sd-page .sd-head__body .sd-cue {
  margin-top: auto;
  padding-top: 0.9em;
}
.sd-page .sd-head__body p:nth-last-child(2) {
  margin-bottom: clamp(32px, 4vw, 56px);
}

/* "Flexible Development Support" fits on one line in the wider lead column;
   below 1200px balance splits it evenly instead of stranding "Support". */
@media (min-width: 1200px) {
  .sd-page .sd-scale-wrap__lead .sd-h2 {
    white-space: nowrap;
    font-size: clamp(27px, 2.95vw, 44px);
  }
}

/* Mobile section rhythm: one step between sections instead of ~150px. */
@media (max-width: 767.98px) {
  .sd-page {
    --sd-space: 52px;
  }
}
