/* =========================================================
   ROLE TREE  ( .rt-* )
   ---------------------------------------------------------
   Portable, self-contained component for the role-index hubs
   (Job Descriptions, Interview Questions, Salary Guides,
   Resume Screening, How to Hire). Namespaced `rt-*` so it can
   be dropped onto any page without touching the shared
   .playbook-* system.

   Families run horizontally across each row, and their roles
   hang vertically beneath each family node on a rail. No canvas
   surface, no tint, no dot grid, no frame, no top bus.

   Markup is generated by scripts/build-role-tree.py from
   public/data/tech-roles.json. There is no JavaScript: every
   link is in the served HTML.
========================================================= */

.rt{
  padding: 34px 22px 78px;
}

.rt-inner{
  max-width: 1120px;
  margin: 0 auto;
}

/* ---------------------------------------------------------
   Page shell + hero
   Clean centred hero: breadcrumbs, title, a two-sentence
   blurb, the Free Strategy Call, and the author credential.
   Nothing else. The chart below is the working surface, so the
   top of the page stays quiet.
--------------------------------------------------------- */

.rt-page{
  background: #fff;
}

.rt-hero{
  padding: clamp(48px, 6.5vw, 84px) 22px clamp(46px, 5.2vw, 66px);
  text-align: center;
  color: #fff;

  /* Darker end of the brand blue: a deep navy-blue up to --dark-blue (#003e82)
     and just past it, rather than running out to the bright #0071eb. Plus a
     soft highlight behind the title so the block has some depth. */
  background:
    radial-gradient(760px 380px at 50% -8%, rgba(255,255,255,.13), transparent 68%),
    linear-gradient(135deg, #00224a 0%, #003e82 62%, #004e9c 100%);
}

.rt-hero-inner{
  max-width: 880px;
  margin: 0 auto;
}

.rt-hero-crumbs{
  display: flex;
  justify-content: center;
  flex-wrap: wrap;
  align-items: center;
  gap: 4px 8px;

  font-size: 13px;
  font-weight: 600;
  color: rgba(255,255,255,.72);
}

.rt-hero-crumbs a{
  color: rgba(255,255,255,.72);
  text-decoration: none;
  transition: color .15s ease;
}

.rt-hero-crumbs a:hover{
  color: #fff;
}

.rt-hero-crumbs [aria-current="page"]{
  color: #fff;
}

.rt-hero-crumbs-sep{
  color: rgba(255,255,255,.38);
}

.rt-hero-title{
  margin-top: 20px;
  font-size: clamp(38px, 5.2vw, 60px);
  font-weight: 800;
  line-height: 1.05;
  letter-spacing: -0.04em;
  color: #fff;
}

.rt-hero-lede{
  margin: 20px auto 0;
  max-width: 620px;
  font-size: clamp(16px, 1.5vw, 18px);
  line-height: 1.65;
  color: rgba(255,255,255,.82);
}

/* Buttons invert on the blue field: the filled action goes white so it stays the
   dominant one, and the secondary becomes a translucent outline. Scoped to the
   hero, so .btn-primary / .btn-secondary are untouched everywhere else. */
.rt-hero .btn-primary{
  background: #fff;
  color: var(--blue);
  box-shadow: 0 10px 24px rgba(0,20,60,.24);
}

.rt-hero .btn-primary:hover{
  background: #eef4ff;
}

.rt-hero .btn-secondary{
  background: rgba(255,255,255,.12);
  color: #fff;
  border: 1px solid rgba(255,255,255,.42);
  box-shadow: none;
}

.rt-hero .btn-secondary:hover{
  background: rgba(255,255,255,.20);
}

.rt-hero .btn:focus-visible{
  outline: none;
  box-shadow: 0 0 0 3px rgba(255,255,255,.7);
}

.rt-hero-actions{
  display: flex;
  justify-content: center;
  flex-wrap: wrap;
  gap: 12px;
  margin-top: 30px;
}

/* Author credential: portrait on the left, name over creds on the right. No
   container. inline-flex rather than flex so the pair centres as one unit
   inside the centred hero instead of stretching across it. */
.rt-hero-byline{
  display: inline-flex;
  align-items: center;
  gap: 14px;
  margin-top: 38px;
  text-align: left;
}

.rt-hero-byline-avatar{
  width: 56px;
  height: 56px;
  border-radius: 50%;
  object-fit: cover;
  /* A ring rather than a border, so it lifts off the blue without a hard edge */
  box-shadow: 0 0 0 3px rgba(255,255,255,.22);
}

.rt-hero-byline-name{
  font-size: 14px;
  font-weight: 700;
  letter-spacing: -0.01em;
  color: #fff;
}

.rt-hero-byline-name a{
  color: inherit;
  text-decoration: none;
}

.rt-hero-byline-name a:hover{
  text-decoration: underline;
  text-underline-offset: 3px;
}

.rt-hero-byline-role{
  margin-top: 3px;
  font-size: 13px;
  line-height: 1.45;
  color: rgba(255,255,255,.75);
}

html[lang="ja"] .rt-hero-title{
  font-size: clamp(30px, 4vw, 46px);
  line-height: 1.28;
  letter-spacing: 0;
}

html[lang="ja"] .rt-hero-lede{
  line-height: 1.9;
}

@media (max-width: 640px){
  .rt-hero{
    padding: 38px 18px 34px;
  }

  .rt-hero-actions .btn{
    width: 100%;
  }
}


/* ---------------------------------------------------------
   Hub intro block
   The "page intro" section of an SEO hub page, sitting between
   the hero and the chart.
--------------------------------------------------------- */

.rt-intro{
  max-width: 1120px;
  margin: 0 auto;
  padding: clamp(46px, 5.5vw, 68px) 22px 0;
  text-align: center;
}

.rt-intro-body{
  max-width: 720px;
  margin: 0 auto;
}

.rt-intro-title{
  font-size: clamp(24px, 2.8vw, 32px);
  font-weight: 700;
  line-height: 1.2;
  letter-spacing: -0.025em;
  color: var(--text-main);
}

/* Three beats of the argument, side by side, divided by hairlines: why this
   hire matters, what makes it hard, what you get. Left-aligned inside the
   columns, because centred text in a 340px column reads badly. */
.rt-intro-cols{
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  margin-top: clamp(32px, 3.6vw, 46px);
  text-align: left;
}

.rt-intro-col{
  padding: 0 clamp(16px, 2vw, 28px);
}

/* Divider on the inner edges only, never the outer ones */
.rt-intro-col + .rt-intro-col{
  border-left: 1px solid var(--border-subtle);
}

.rt-intro-col:first-child{
  padding-left: 0;
}

.rt-intro-col:last-child{
  padding-right: 0;
}

.rt-intro-text{
  font-size: 17px;
  line-height: 1.7;
  color: var(--text-muted);
}

.rt-intro-text a{
  color: var(--blue);
  font-weight: 600;
  text-decoration: none;
}

.rt-intro-text a:hover{
  text-decoration: underline;
  text-underline-offset: 2px;
}

/* Closing offer, pulled out of the third column and set under the whole block:
   centred, larger, and darker than the column prose so it reads as the section's
   conclusion rather than a fourth paragraph. */
.rt-intro-note{
  max-width: 720px;
  margin: clamp(34px, 3.6vw, 48px) auto 0;

  font-size: 19px;
  line-height: 1.6;
  color: var(--text-main);
}

.rt-intro-note a{
  color: var(--blue);
  font-weight: 600;
  text-decoration: none;
}

.rt-intro-note a:hover{
  text-decoration: underline;
  text-underline-offset: 2px;
}

html[lang="ja"] .rt-intro-note{
  font-size: 18px;
  line-height: 1.85;
}

/* Stacked below the point where three columns stop being readable: dividers
   rotate from vertical to horizontal. */
@media (max-width: 880px){
  .rt-intro-cols{
    grid-template-columns: 1fr;
    max-width: 640px;
    margin-left: auto;
    margin-right: auto;
  }

  .rt-intro-col{
    padding: 0;
  }

  .rt-intro-col + .rt-intro-col{
    margin-top: 26px;
    padding-top: 26px;
    border-left: none;
    border-top: 1px solid var(--border-subtle);
  }
}

html[lang="ja"] .rt-intro-title{
  letter-spacing: 0;
  line-height: 1.35;
}

html[lang="ja"] .rt-intro-text{
  line-height: 1.95;
}


/* ---------------------------------------------------------
   Section head
--------------------------------------------------------- */

.rt-head{
  max-width: 740px;
  margin: 0 auto;
  text-align: center;
}

.rt-title{
  font-size: clamp(28px, 3.6vw, 40px);
  font-weight: 700;
  line-height: 1.15;
  letter-spacing: -0.03em;
  color: var(--text-main);
}

.rt-lede{
  margin-top: 14px;
  font-size: var(--default);
  line-height: 1.7;
  color: var(--text-muted);
}


/* Icon sprite: the category glyphs are defined once and referenced by every
   node, instead of inlining the same path 70 times. */
.rt-sprite{
  position: absolute;
  width: 0;
  height: 0;
  overflow: hidden;
}


/* ---------------------------------------------------------
   Chart
   Families run across each row, roles hang vertically beneath
   each family node.

   Rows are explicit elements rather than one auto-flowing grid
   because which families sit side by side is an editorial
   decision, declared as `chartRows` in the registry. Every row
   runs on the same track, sized from the widest row via
   --rt-cols, so a short row simply leaves its trailing slots
   empty and every card keeps the same width.
--------------------------------------------------------- */

.rt-tree{
  display: grid;
  gap: 46px;
  margin-top: 34px;
}

.rt-row{
  display: grid;
  grid-template-columns: repeat(var(--rt-cols, 4), 1fr);
  gap: 0 20px;
  align-items: start;
}

.rt-branch{
  position: relative;
  min-width: 0;
  scroll-margin-top: 96px;
}


/* ---------------------------------------------------------
   Family node
   The parent card. Its glyph circle is solid accent, where a
   role node's is tinted, so the two levels are distinguishable
   at a glance.
--------------------------------------------------------- */

.rt-family{
  display: flex;
  align-items: center;
  gap: 10px;

  margin: 0;
  min-height: 58px;
  padding: 10px 12px;
  border-radius: 14px;
  border: 1px solid rgba(15,23,42,.09);
  background: #fff;
  box-shadow:
    0 1px 2px rgba(15,23,42,.05),
    0 14px 24px -18px rgba(15,23,42,.6);
}

.rt-family-mark{
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;

  width: 32px;
  height: 32px;
  border-radius: 50%;
  background: rgb(var(--rt-accent-rgb));
  color: #fff;
}

.rt-family-mark svg{
  width: 17px;
  height: 17px;
}

.rt-family-name{
  min-width: 0;
  font-size: 13.5px;
  font-weight: 700;
  line-height: 1.3;
  letter-spacing: -0.015em;
  color: var(--text-main);
}

.rt-family-count{
  flex: 0 0 auto;
  margin-left: auto;
  padding-left: 8px;

  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.06em;
  color: var(--text-muted);
  font-variant-numeric: tabular-nums;
}


/* ---------------------------------------------------------
   Role nodes
   Stacked vertically under their family, on a rail that drops
   from the family node with an elbow into each role. The rail
   is drawn per item so it stops cleanly at the last one.
--------------------------------------------------------- */

.rt-list{
  display: grid;
  gap: 7px;
  margin: 0;
  padding: 13px 0 0 22px;
  list-style: none;
}

.rt-item{
  position: relative;
  min-width: 0;
}

/* Rail through this item, extended into the gap below it */
.rt-item::before{
  content: "";
  position: absolute;
  left: -13px;
  top: -7px;
  bottom: -7px;
  width: 2px;
  background: rgba(var(--rt-accent-rgb), .24);
}

/* The first rail segment reaches up to the family node */
.rt-item:first-child::before{
  top: -20px;
}

/* The last one stops at its own elbow instead of running on */
.rt-item:last-child::before{
  bottom: 50%;
}

/* Elbow into the role node */
.rt-item::after{
  content: "";
  position: absolute;
  left: -13px;
  top: 50%;
  width: 13px;
  height: 2px;
  background: rgba(var(--rt-accent-rgb), .24);
}

.rt-role{
  display: flex;
  align-items: center;
  gap: 8px;

  padding: 8px 10px;
  border-radius: 11px;
  border: 1px solid rgba(15,23,42,.075);
  background: #fff;
  box-shadow: 0 1px 2px rgba(15,23,42,.04);

  text-decoration: none;
  color: inherit;

  transition: transform .16s ease, box-shadow .16s ease, border-color .16s ease;
}

.rt-role-name{
  min-width: 0;
  overflow-wrap: anywhere;
  font-size: 13px;
  font-weight: 600;
  line-height: 1.35;
  letter-spacing: -0.01em;
  color: var(--text-main);
  transition: color .16s ease;
}

.rt-role-arrow{
  flex: 0 0 auto;
  width: 14px;
  height: 14px;
  margin-left: auto;
  color: rgb(var(--rt-accent-rgb));

  opacity: 0;
  transform: translateX(-4px);
  transition: opacity .16s ease, transform .16s ease;
}

a.rt-role:hover{
  transform: translateY(-1px);
  border-color: rgba(var(--rt-accent-rgb), .42);
  box-shadow:
    0 2px 4px rgba(15,23,42,.05),
    0 12px 22px -14px rgba(var(--rt-accent-rgb), .7);
}

a.rt-role:hover .rt-role-name{
  color: rgb(var(--rt-accent-rgb));
}

a.rt-role:hover .rt-role-arrow,
a.rt-role:focus-visible .rt-role-arrow{
  opacity: 1;
  transform: translateX(0);
}

a.rt-role:focus-visible{
  outline: none;
  border-color: rgba(var(--rt-accent-rgb), .55);
  box-shadow: 0 0 0 3px rgba(var(--rt-accent-rgb), .28);
}

/* Not-yet-published role: inert, dashed, never a dead link. */
.rt-role--soon{
  border-style: dashed;
  border-color: rgba(15,23,42,.13);
  background: transparent;
  box-shadow: none;
  cursor: default;
}

.rt-role--soon .rt-role-name{
  color: #8b94a5;
  font-weight: 500;
}

.rt-role-tag{
  flex: 0 0 auto;
  margin-left: auto;
  padding-left: 6px;

  font-size: 9.5px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: #a3abb8;
  white-space: nowrap;
}


/* ---------------------------------------------------------
   CTA block  ( .rt-cta )
   The shared .playbook-bottom-cta lays its inner out as a
   two-column grid, which leaves a wide empty second column on a
   page that has nothing to put there. This modifier collapses it
   to one centred column. Scoped with an extra class rather than
   edited in place, because every other playbook page still wants
   the two-column version.
--------------------------------------------------------- */

.rt-cta .playbook-bottom-cta-inner{
  grid-template-columns: 1fr;
  padding: clamp(34px, 4vw, 54px) clamp(24px, 4vw, 48px);
}

.rt-cta .playbook-bottom-cta-copy{
  max-width: 720px;
  margin: 0 auto;
  text-align: center;
}

.rt-cta .playbook-bottom-cta-text{
  max-width: 62ch;
  margin-left: auto;
  margin-right: auto;
}

.rt-cta .playbook-bottom-cta-actions{
  justify-content: center;
}


/* ---------------------------------------------------------
   Anatomy list  ( .rt-anatomy )
   Flat two-column list used on role pages. Hairline per row,
   colour carried by the numeral only. No cards, no nested
   boxes.
--------------------------------------------------------- */

.rt-anatomy{
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
  column-gap: clamp(28px, 4vw, 64px);
}

.rt-anatomy-item{
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 18px;

  padding: 22px 0;
  border-top: 1px solid var(--border-subtle);
}

.rt-anatomy-num{
  font-size: 19px;
  font-weight: 800;
  line-height: 1.3;
  letter-spacing: -0.02em;
  color: rgb(var(--rt-accent-rgb));
  font-variant-numeric: tabular-nums;
}

.rt-anatomy-name{
  font-size: var(--default);
  font-weight: 700;
  line-height: 1.4;
  letter-spacing: -0.015em;
  color: var(--text-main);
}

.rt-anatomy-text{
  margin-top: 7px;
  font-size: var(--small);
  line-height: 1.7;
  color: var(--text-muted);
}

html[lang="ja"] .rt-anatomy-name{
  letter-spacing: 0;
  line-height: 1.5;
}

html[lang="ja"] .rt-anatomy-text{
  line-height: 1.85;
}


/* ---------------------------------------------------------
   Accents
   One RGB triplet per category drives the glyph, dot, dashed
   border, hover tint, and arrow.

   Scoped to .rt / .rt-anatomy so the shared `data-accent`
   attribute used elsewhere in playbook.css is never touched.
--------------------------------------------------------- */

.rt,
.rt-anatomy{                                        --rt-accent-rgb:   0, 113, 235; }

.rt [data-accent="blue"],    .rt-anatomy[data-accent="blue"]    { --rt-accent-rgb:   0, 113, 235; }
.rt [data-accent="slate"],   .rt-anatomy[data-accent="slate"]   { --rt-accent-rgb:  71,  85, 105; }
.rt [data-accent="purple"],  .rt-anatomy[data-accent="purple"]  { --rt-accent-rgb: 107,  77, 230; }
.rt [data-accent="green"],   .rt-anatomy[data-accent="green"]   { --rt-accent-rgb:   0, 154,  68; }
.rt [data-accent="cyan"],    .rt-anatomy[data-accent="cyan"]    { --rt-accent-rgb:   8, 145, 178; }
.rt [data-accent="red"],     .rt-anatomy[data-accent="red"]     { --rt-accent-rgb: 235,   0,  58; }
.rt [data-accent="teal"],    .rt-anatomy[data-accent="teal"]    { --rt-accent-rgb:  13, 148, 136; }
.rt [data-accent="orange"],  .rt-anatomy[data-accent="orange"]  { --rt-accent-rgb: 235, 122,   0; }
.rt [data-accent="indigo"],  .rt-anatomy[data-accent="indigo"]  { --rt-accent-rgb:  79,  70, 229; }
.rt [data-accent="navy"],    .rt-anatomy[data-accent="navy"]    { --rt-accent-rgb:  30,  58, 138; }
.rt [data-accent="magenta"], .rt-anatomy[data-accent="magenta"] { --rt-accent-rgb: 192,  38, 211; }
.rt [data-accent="amber"],   .rt-anatomy[data-accent="amber"]   { --rt-accent-rgb: 180,  83,   9; }
.rt [data-accent="pink"],    .rt-anatomy[data-accent="pink"]    { --rt-accent-rgb: 219,  39, 119; }


/* ---------------------------------------------------------
   Responsive
   The spine and connectors are decoration, not information, so
   below 640px they go and the chart becomes a stacked list of
   labelled groups.
--------------------------------------------------------- */

@media (max-width: 1040px){
  .rt-row{
    grid-template-columns: repeat(3, 1fr);
    gap: 38px 20px;
  }

  .rt-tree{
    gap: 38px;
  }
}

@media (max-width: 800px){
  .rt-row{
    grid-template-columns: repeat(2, 1fr);
  }
}

@media (max-width: 560px){
  .rt{
    padding: 26px 18px 60px;
  }

  .rt-row{
    grid-template-columns: 1fr;
    gap: 32px;
  }

  .rt-tree{
    gap: 32px;
  }

  .rt-role-arrow{
    opacity: .5;
    transform: none;
  }
}


/* ---------------------------------------------------------
   Japanese locale
   Japanese has no word spacing, so the tightened tracking used
   for Latin display type reads cramped.
--------------------------------------------------------- */

html[lang="ja"] .rt-title{
  letter-spacing: -0.01em;
  line-height: 1.3;
}

html[lang="ja"] .rt-family-name,
html[lang="ja"] .rt-role-name{
  letter-spacing: 0;
}

html[lang="ja"] .rt-lede{
  line-height: 1.85;
}


/* ---------------------------------------------------------
   Motion preference
--------------------------------------------------------- */

@media (prefers-reduced-motion: reduce){
  .rt-role,
  .rt-role-name,
  .rt-role-arrow{
    transition: none;
  }

  a.rt-role:hover{
    transform: none;
  }
}
