/* ─────────────────────────────────────────────────────────────────────────
   jt-mobile.css - the phone/tablet layer for every page.

   The site is a design-tool export: nearly all layout lives in inline style
   attributes, so nothing here can win on specificity alone. Every declaration
   is !important by necessity, and every rule sits inside a max-width query.
   Above 768px this file contributes nothing - the desktop layout is untouched.

   The rules only ever hang off the .jt-* hooks added to the markup, so a
   re-export that changes an inline value does not silently change the phone
   layout in a different direction than the desktop one.
   ───────────────────────────────────────────────────────────────────────── */

@media (max-width: 768px) {

  /* ── page shell ──────────────────────────────────────────────────────── */
  /* the ghost numerals and rotated watermarks are sized in vh and hang off
     the section edges; at phone widths they are wider than the viewport and
     the only thing they add is a horizontal scrollbar */
  .jt-ghost { display: none !important; }

  /* NB: do not put overflow-x on <html>. Every page already sets it on <body>,
     and adding it to the root turns the root into the scroll container, which
     collapses the document to a single viewport and kills scrolling outright. */
  html { scroll-padding-top: 66px !important; }

  /* ── the CRT navbar ──────────────────────────────────────────────────── */
  /* Desktop centres six links in the bar and drops a mega-menu under whichever
     one the pointer is on. On a 390px screen the row shows two and a half of
     them behind a sideways scroll, and the mega-menu is unreachable without a
     pointer - so between them, four of the six sections are effectively gone.
     Both come out of the bar here. jt-mobile-nav.js puts the MENU button in
     their place and rebuilds all six sections, and every sub-item the
     mega-menu had, as a tap-to-expand sheet.
     The bar is then just the wordmark and that button, which is why the logo
     lockup needs no shrinking at this width. */
  .jt-nav-strip { display: none !important; }
  .jt-nav-drawer { display: none !important; }

  /* With the links gone the bar holds the wordmark and the MENU button. The
     wordmark sits at left:54px on desktop because the docked corner mark lands
     to its left; that mark is hidden here, so the lockup centres in the bar
     instead of floating off one edge. It is ~110px wide against a button that
     starts at ~300px, so the two never meet. */
  /* Centred with auto margins against all four insets, not with a translate.
     A transform creates a stacking context, which would trap the mark below
     the bar's scanline overlays no matter what z-index it asked for. Sizing to
     max-content also keeps the anchor from becoming a bar-wide tap target that
     sends you home on any stray touch. */
  .jt-nav-logo {
    inset: 0 !important;
    width: max-content !important;
    height: max-content !important;
    margin: auto !important;
    transform: none !important;
    z-index: auto !important;
    grid-template-columns: auto auto !important;
    column-gap: 9px !important;
    align-items: center !important;
  }
  /* The mark rides in the lockup here because the corner stamp that normally
     docks into this spot is hidden on phones. It spans both rows so the
     wordmark and its justified subline stack beside it, and it is inverted
     because the source art is black and the bar is a black CRT. */
  .jt-nav-mark {
    display: block !important;
    grid-column: 1 !important;
    grid-row: 1 / span 2 !important;
    width: auto !important;
    height: 25px !important;
    /* Cream, not white: this sits directly beside the JAGDUSHAH wordmark
       (#E7E1D0), and a pure-white glyph next to cream type reads as two
       different inks. Same chain the docked desktop stamp ends on. */
    filter: invert(1) sepia(1) saturate(1.59) brightness(0.906) !important;
    /* Above the bar's grain and scanline overlays, which sit at z-index 3 and
       4. On the wordmark that texture reads as phosphor; on a solid glyph it
       reads as damage, which is why the desktop stamp floats above them too.
       Dropping the anchor's own z-index removes the stacking context that
       would otherwise trap this underneath. */
    position: relative !important;
    z-index: 5 !important;
  }

  /* the corner mark rides up the right edge and slides left along the bar as
     you scroll. Desktop keeps ~190px of bar clear for it to land in; a phone
     bar has no such lane, so for most of the scroll the mark is a logo sitting
     on top of the nav links and, before that, on top of the CRT. The wordmark
     beside it already carries the brand in the bar. */
  .jt-stamp { display: none !important; }

  /* ── arcade: off on phones ───────────────────────────────────────────── */
  /* Pac-Man and Tetris are keyboard games behind a 4-way D-pad that lands at
     28px on a phone, and the drifting icon sits over page content. The whole
     feature comes out rather than shipping a version that cannot be played. */
  #arcade,
  .jt-fly,
  .jt-fly-inline,
  .jt-arcade-modal { display: none !important; }

  /* ══ landing page ═════════════════════════════════════════════════════ */

  /* ── hero: the mechanical keyboard ───────────────────────────────────── */
  /* Two things made the hero read as empty. The board was pinned small by the
     widest headline line (regrouped for narrow screens in the template), and
     the section still claimed a full 100vh to hold it - a ~300px board centred
     in 844px leaves 250px of blank paper above and below. Between the two, the
     board went from filling ~36% of the hero to ~66%. Below ~500px tall the
     padding sets the height and this min never binds. */
  #top {
    padding: 78px 3vw 30px !important;
    min-height: 62svh !important;
  }
  /* the case is a fixed pixel width from JS - never let it push the page wide */
  .jt-board { max-width: 100% !important; }

  /* ── hero: the CRT question strip ────────────────────────────────────── */
  /* The strip is one flex row: knob cluster, screen, lamps and POWER. The two
     clusters are a fixed ~190px of that row, so on a 324px board the screen is
     left with under 100px - about ten characters of a question that runs to
     fifty-four. Every phrase was cut mid-word ("want a crm ").
     Rather than drop the furniture, the screen wraps onto its own full-width
     line beneath it: ~46 characters a line, two lines, so the longest question
     lands whole. */
  .jt-kb-strip {
    flex-wrap: wrap !important;
    height: auto !important;
    row-gap: 7px !important;
  }
  .jt-kb-lamps { order: 2 !important; margin-left: auto !important; }
  .jt-crt {
    order: 3 !important;
    flex: 0 0 100% !important;
    height: auto !important;
  }
  /* min-height holds two lines from the start: the text is typed a character
     at a time, and without it the strip would grow the moment a question
     wrapped and shunt the whole board down mid-sentence */
  .jt-crt-line {
    height: auto !important;
    min-height: 2.9em !important;
    align-items: flex-start !important;
    white-space: normal !important;
    line-height: 1.45 !important;
    padding: 6px 0.9em 7px !important;
  }
  /* the caret is the third flex child, so once the text wraps it parks itself
     beside the block rather than after the last letter. Inline on the text
     instead, where it follows the cursor the way a terminal's does. */
  .jt-crt-caret { display: none !important; }
  .jt-crt-text::after {
    content: "";
    display: inline-block;
    width: 0.55em;
    height: 1.05em;
    margin-left: 0.12em;
    vertical-align: -0.15em;
    background: var(--kb-red);
    box-shadow: 0 0 10px rgba(222, 50, 38, 0.85);
    animation: jtblink 1.05s steps(1) infinite;
  }

  /* ── services: sticky stage ──────────────────────────────────────────── */
  /* Desktop is a 320px list beside the monitor. That does not survive a
     single column, so the monitor goes on top (it is the content) and the
     service list becomes the strip of channel buttons under it. */
  /* minmax(0, 1fr), not 1fr: a bare 1fr column takes its minimum from the
     content, and the laptop screen holds `white-space: pre` code whose
     min-content width is hundreds of pixels wider than the phone. That blows
     the column out and every paragraph sharing it runs off the screen. */
  .jt-svc-stage {
    grid-template-columns: minmax(0, 1fr) !important;
    grid-template-rows: auto auto minmax(0, 1fr) !important;
    /* the stage pins at top:0, so its first row starts under the 58px bar */
    padding-top: 66px !important;
  }

  /* Both stages hang their section title absolutely over the stage and push
     the content clear of it with a fixed top padding. That number can only be
     right at one width: at 390 it left 15px of air, at 768 the eyebrow sat on
     the monitor's bezel. In a single column the title does not need to float -
     it becomes the first row and the overlap cannot happen. It also hands back
     the ~60px the padding was over-reserving. */
  .jt-svc-stage > div:first-child,
  .jt-stk-stage > div:first-child {
    position: static !important;
    top: auto !important;
    padding: 0 4vw !important;
    margin-bottom: 10px !important;
  }
  .jt-svc-stage > div:first-child { order: 0 !important; }
  .jt-svc-monitor {
    order: 1 !important;
    padding: 0 4vw 4px !important;
    align-items: stretch !important;
  }
  .jt-svc-list { order: 2 !important; }

  /* The tube is a fixed height and the copy inside it is absolutely
     positioned, so anything that does not fit is simply cut - at 390 that was
     151px, which took the whole capability list and half the line above it.
     The chassis and bezel are 34px of moulding a phone cannot afford, so the
     tube takes that back, the copy inside tightens, and the list is capped at
     the first five chips (all eight live on the Services page). */
  .jt-svc-chassis {
    padding: 8px 8px 0 !important;
    border-radius: 12px 12px 5px 5px !important;
  }
  .jt-svc-bezel { padding: 9px !important; border-radius: 9px !important; }
  .jt-svc-plate { padding: 7px 2px 8px !important; }
  /* height:auto, not another fixed clamp. The copy inside the tube is
     position:absolute, so a fixed height silently crops whatever does not fit
     and the amount cropped changes with each service's description. Letting
     the copy sit in flow makes the tube take its own height, so nothing can be
     cut no matter which service is on screen or how long its text runs. */
  .jt-svc-screen {
    height: auto !important;
    min-height: clamp(200px, 32vh, 300px) !important;
    border-radius: 12px !important;
  }
  .jt-svc-content { position: static !important; }
  /* the monitor shell carries an inline max-height:100% so it cannot outgrow
     the desktop stage. Against an auto grid row that caps the tube again and
     re-crops the longer services - the whole point of the rule above. */
  .jt-svc-monitor > div:last-child { max-height: none !important; }
  .jt-svc-content { padding: 13px !important; gap: 6px !important; }
  /* margin-top:auto pushed the title down a fixed-height tube; in flow it
     would only add dead space above the copy */
  .jt-svc-content > * { margin-top: 0 !important; }
  .jt-svc-chips > span:nth-child(n+6) { display: none !important; }
  /* "scroll ↓" - the page scrolls on its own here and the hint costs a line */
  .jt-svc-scroll { display: none !important; }

  /* the dot-matrix glyph is parked in the screen's top-right corner and the
     copy is allowed to run under it at desktop widths because the copy stops
     at 560px. At 340px the paragraph runs straight through it. */
  .jt-svc-glyph { display: none !important; }

  .jt-svc-list {
    border-right: 0 !important;
    border-top: 2px solid var(--color-text) !important;
    padding: 8px 4vw 12px !important;
    background: rgba(227, 223, 211, 0.94) !important;
  }

  /* ── why us: the card carousel ───────────────────────────────────────── */
  /* JS already drops to one card per view below 760px. Flanking that one card
     with arrows costs it a third of the screen, so the arrows wrap underneath
     and the card gets the full column. */
  .jt-why-row {
    flex-wrap: wrap !important;
    justify-content: center !important;
    gap: 14px !important;
  }
  .jt-why-row > div {
    flex: 1 1 100% !important;
    order: -1 !important;
  }
  .jt-why-arrow {
    width: 56px !important;
    height: 44px !important;
    align-self: auto !important;
  }

  /* ── technologies: sticky stage ──────────────────────────────────────── */
  .jt-stk-stage {
    grid-template-columns: minmax(0, 1fr) !important;
    grid-template-rows: auto auto minmax(0, 1fr) !important;
    align-items: start !important;
    gap: 12px !important;
    padding: 74px 5vw 24px !important;
  }

  /* the laptop sways 26px each way and is rotated up to 14deg on its Y axis.
     Both read as depth on a wide canvas and as a clipped, tilted rectangle on
     a phone, so it lies flat here. */
  .jt-stk-laptop { animation: none !important; perspective: none !important; }
  .jt-stk-laptop > div { transform: none !important; }
  /* the stage is 100vh and holds the laptop above the copy. The laptop is a
     16/10 screen, so on a short viewport it grows with the width and pushes
     the copy past the bottom of a stage that clips. Tie its width to the
     height available instead: 38vh of screen, times the 1.6 aspect. Above
     ~800px tall the cap exceeds the column and does nothing. */
  .jt-stk-laptop {
    max-width: calc(38vh * 1.6) !important;
    margin-left: auto !important;
    margin-right: auto !important;
  }
  /* 320px of forced height on a 16/10 screen that is only ~340px wide */
  .jt-stk-screen { min-height: 0 !important; }

  .jt-stk-copy h2 { font-size: clamp(26px, 7.4vw, 38px) !important; }
  .jt-stk-copy p { font-size: 15px !important; margin-bottom: 14px !important; }

  /* ── speed: the typing test ──────────────────────────────────────────── */
  /* The test is 30 seconds of typing against a live WPM counter. A phone has
     no physical keyboard, and the on-screen one cannot be summoned by a page
     with no input in it - so the test surface and its key legend come out and
     the panel keeps the copy and the result frame. */
  #speed { padding: 56px 5vw !important; }
  #speed h2 { font-size: clamp(28px, 8vw, 44px) !important; }

  .jt-test { padding: 18px !important; }
  .jt-test > div:first-of-type { display: none !important; }
  .jt-test-keys { display: none !important; }

  .jt-test-overlay {
    position: static !important;
    background: transparent !important;
    padding: 0 !important;
    gap: 14px !important;
  }
  /* the mouse is the test's start control: three buttons for three modes.
     With it gone, its instructions ("left button for a thirty second sprint…")
     describe controls that are no longer on the page, so the whole prompt is
     replaced with one line that says what is actually true here. */
  .jt-test-overlay > div:last-child { display: none !important; }
  .jt-test-overlay > div:first-child > div,
  .jt-test-overlay > div:first-child > p { display: none !important; }
  .jt-test-overlay > div:first-child::after {
    content: "The keyboard test needs a physical keyboard. Open this page on a desktop to take it.";
    display: block;
    font-family: var(--font-mono);
    font-size: 12px;
    line-height: 1.7;
    letter-spacing: 0.06em;
    color: var(--color-neutral-400);
  }

  /* ── section headings in outline type ────────────────────────────────── */
  /* locked to nowrap so the stroke reads as one word; shrink rather than wrap */
  .jt-outline-h {
    font-size: clamp(24px, 7.2vw, 34px) !important;
    -webkit-text-stroke-width: 1.5px !important;
  }
  /* The eyebrow under it is flanked by two short rules that end up stranded on
     different lines once it wraps, so they go. The eyebrow itself must then
     hold one line: the title block is absolutely positioned over the section,
     and a second line lands behind the monitor. At 0.24em of tracking the
     longest of them ("five practices, everything you need built") needs 344px
     - exactly the content width of a 390px phone. Tightening the tracking to
     0.12em buys ~50px of margin. */
  .jt-outline-h + span {
    flex-wrap: wrap !important;
    font-size: 10px !important;
    letter-spacing: 0.08em !important;
  }
  .jt-outline-h + span > span { display: none !important; }

  /* ── contact / footer ────────────────────────────────────────────────── */
  #contact { padding: 64px 5vw !important; }
  #contact p { font-size: 17px !important; }

  /* ══ inner pages (About / Industries / Projects / Services / Technologies) ══ */
  /* every one opens with `padding: 104px 6vw …` under a 58px bar */
  section[style*="padding: 104px 6vw"] { padding-top: 86px !important; }

  /* the rack / file header is a five-item flex row: emblem, title block, LED
     strip, unit count, expand mark. The first four fixed items claim ~255px of
     a 354px row, which squeezes the title block to nothing and the heading
     paints straight over its neighbours. The status furniture goes; the title
     and the expand mark are what the row is for. */
  .jt-file-head { gap: 12px !important; }
  .jt-file-head > span:not(:last-child) { display: none !important; }

  /* Card headers keep their one line of copy on one line and ellipsise the
     overflow. That is a fair trade at 1200px, where it clips a word or two;
     at 311px it eats half the sentence ("Consulting / architecture / custom…",
     "Cross-industry (enterprises running…"). On a phone the line is allowed to
     wrap instead - vertical space is the cheap axis here. */
  .jt-ellip {
    white-space: normal !important;
    overflow: visible !important;
    text-overflow: clip !important;
  }

  /* About: the roster's five-column header cannot fit 390px, and the rows
     under it wrap - so the columns stop lining up with their labels anyway.
     The rows carry their own meaning; the header just overflowed. */
  .jt-roster-head { display: none !important; }

  /* Projects: the filter bar sticks under the navbar. Five chips that sit on
     one line at desktop wrap to four rows on a phone, so pinning it would park
     ~170px of chrome on top of every card for the length of the page. */
  div[style*="position: sticky; top: 58px"] { position: static !important; }
}

/* ── short portrait screens (SE-class phones) ──────────────────────────── */
/* 640px of height has to hold a section title, a 16/10 screen and a paragraph
   of copy inside one sticky stage. Buy the room back from the title gutter and
   from the screen, in that order. */
@media (max-width: 768px) and (max-height: 700px) {
  .jt-svc-screen { min-height: 170px !important; }
  .jt-svc-content { padding: 10px !important; }
  .jt-stk-stage { padding-top: 68px !important; }
  .jt-stk-laptop { max-width: calc(30vh * 1.6) !important; }
}

/* ── short screens: landscape phones and SE-class devices ──────────────── */
/* Below ~660px of height there is no arrangement of a section title, a 16/10
   screen and its copy that fits inside a 100vh sticky stage without either
   shrinking the screen to a stamp or clipping the copy. So the two
   scroll-driven sections stop being sticky here and simply flow down the page:
   the scroll choreography is lost, none of the content is. */
@media (max-width: 900px) and (max-height: 660px) {
  #services, #stack { height: auto !important; }
  .jt-svc-stage,
  .jt-stk-stage {
    position: static !important;
    height: auto !important;
    padding-top: 68px !important;
  }
  .jt-stk-laptop { max-width: calc(46vh * 1.6) !important; }
}

/* ── phones proper ─────────────────────────────────────────────────────── */
@media (max-width: 480px) {
  /* the service rows lose the ON AIR / READY tag before they lose the name */
  .jt-svc-list [style*="letter-spacing: 0.16em"] { display: none !important; }
}
