/* ============================================================
   LawnBeast V2 — ARTICLE SKIN: guide  (/guides/<slug>)
   Layout 1b in the "SaaS feature content layouts" design doc.

   Task-sized how-to: prerequisites, numbered steps, a settings
   reference table, troubleshooting, related guides.

   Concept pages (e.g. jobs-vs-invoices) use this same skin and
   simply omit .art-steps / the settings table — a concept is a
   guide without clicks, not a fourth layout. See
   templates/guides/_STARTER.html.

   Loads after css/v2/article/base.css. MOBILE-FIRST.
   ============================================================ */

/* ---------- Head ---------- */
.art--guide .art-title {
    font-size: 26px;
    letter-spacing: -.02em;
    line-height: 1.15;
}
.art--guide .art-lede {
    margin-bottom: 24px;
}

/* ---------- Rail meta (updated / read time / level) ---------- */
.art-railmeta {
    margin-top: 16px;
    padding-top: 14px;
    border-top: 1px solid var(--border);
    font-size: 11px;
    line-height: 1.6;
    color: var(--text-muted);
}

/* On mobile the rail is a pill strip with no room for this; the same
   facts ride in the head's .art-meta row instead. */
.art--guide .art-railmeta { display: none; }

/* ---------- Width ---------- */
/* The guide skin releases the reading measure entirely: every block — prose
   included — runs the full width of the body column. Redefining the token here
   rather than editing each rule means one declaration covers the lede, <p>,
   lists, callouts, the thesis, the FAQ, quotes and the Q/A stack, and any block
   added later inherits the same answer. The head is inside .art-body in
   tools/guide_article.html, so the title/lede follow.

   Trade-off, stated plainly: at the 1320 xxl tier the column is 992px, which is
   ~130 characters per line at 15px — past the 45–90 the measure existed to
   hold. That is the requested behaviour, not an oversight. Reverting is one
   line: delete this rule.

   The base --art-wide (also 100%) still matters for the other two skins, whose
   bodies keep a cap. */
.art--guide .art-body { --art-measure: 100%; }

/* ---------- Steps ---------- */
.art-steps {
    list-style: none;
    margin: 0 0 26px;
    padding: 0;
    counter-reset: art-step;
}
.art-steps > li {
    position: relative;
    counter-increment: art-step;
    padding-left: 42px;
    margin: 0 0 26px;
    min-width: 0;
}
.art-steps > li:last-child { margin-bottom: 0; }
.art-steps > li::before {
    content: counter(art-step);
    position: absolute;
    left: 0;
    top: 0;
    width: 30px;
    height: 30px;
    border-radius: 50%;
    background: var(--accent);
    color: #fff;
    display: flex;
    align-items: center;
    justify-content: center;
    font-family: var(--art-font-mono);
    font-weight: 700;
    font-size: 14px;
}
/* connector rail down the left, stopping at the last step */
.art-steps > li:not(:last-child)::after {
    content: "";
    position: absolute;
    left: 14px;
    top: 34px;
    bottom: -26px;
    width: 2px;
    background: var(--border-light);
}
.art-steps > li > h3 {
    margin: 3px 0 8px;
    font-size: 16px;
    letter-spacing: -.01em;
}
.art-steps > li > p {
    margin: 0 0 12px;
    font-size: 14px;
    line-height: 1.7;
}
.art-steps > li > *:last-child { margin-bottom: 0; }
/* nested blocks inside a step keep the step's rhythm */
.art-steps .art-callout,
.art-steps .art-figure,
.art-steps .art-table-wrap { margin-bottom: 0; }

/* Steps carry deep-linked ids (#step-1..5 on the TestFlight guide, linked
   from its overview cards and from outside). base.css offsets only
   .art-body section, so without this a jump parks the step under the nav. */
.art-steps > li[id] { scroll-margin-top: calc(var(--nav-h) + 56px); }

.art-substeps {
    margin: 0 0 12px;
    padding-left: 20px;
}
.art-substeps li { font-size: 13.5px; margin-bottom: 5px; }

.art-default {
    font-size: 12px;
    font-weight: 600;
    color: var(--text-muted);
    background: var(--surface-alt);
    border: 1px solid var(--border-light);
    border-radius: 4px;
    padding: 1px 6px;
    white-space: nowrap;
}

/* ---------- Section rules ---------- */
/* Reference + troubleshooting sit below the steps behind a hairline. */
.art--guide .art-body > section.art-section--ruled {
    border-top: 1px solid var(--border-light);
    padding-top: 24px;
    margin-top: 30px;
}
.art--guide .art-body > section.art-section--ruled > h2 { margin-top: 0; }

/* ---------- Foot ---------- */
.art-nextup {
    margin-top: 28px;
    padding-top: 20px;
    border-top: 1px solid var(--border-light);
}
.art-nextup-head {
    font-size: 10px;
    font-weight: 600;
    letter-spacing: .06em;
    text-transform: uppercase;
    color: var(--text-muted);
    margin-bottom: 10px;
}

/* ============================================================
   Desktop
   ============================================================ */
@media (min-width: 768px) {
    .art--guide .art-title { font-size: 30px; }
    .art-steps > li > h3 { font-size: 17px; }
}

@media (min-width: 1000px) {
    /* Rail on the left, as a tinted column flush to the body —
       the design doc's 214px "On This Page" aside. */
    /* display:grid + align-items:start and the sticky rail offset are shared
       with the feature skin and live in base.css under this same query. */
    .art--guide .art-layout {
        grid-template-columns: 232px minmax(0, 1fr);
        gap: 40px;
        padding-top: 12px;
    }
    .art--guide .art-railmeta { display: block; }
    /* No cap: the body fills its grid cell, which .pub-container already bounds
       (992px at the 1320 xxl tier). The old 720px left ~270px of the column
       empty on a wide monitor while the comparison tables scrolled inside it.
       Prose follows it out too — the --art-measure override above resolves
       every text block's max-width to 100%, so this cap was the only thing
       still holding them. Both halves of that decision live in the Width block
       near the top of this file; read its trade-off note before changing
       either. */
    .art--guide .art-body { max-width: none; }
    .art--guide .art-head { padding-top: 36px; }
}

/* ============================================================
   Carousel — .art-carousel
   ------------------------------------------------------------
   A slide deck for screenshots that are ALTERNATIVES to one
   another (the seven Routes views), not steps in a sequence.
   Steps stay in .art-steps; a reader comparing options wants one
   at a time, and six stacked full-bleed screenshots is a scroll,
   not a comparison.

   ONE CARD, THREE BANDS. The deck reads top to bottom as a single
   object — screenshot, then the controls, then the explanation of
   what you are looking at — because a full-bleed image with prose
   floating under it in the gutter reads as two unrelated things.
   So the whole component is a bordered card, the image sits flush
   inside it, and hairlines separate the bands rather than
   whitespace. The caption is inside the card's border, which is
   what ties the words to the picture.

   NO-JS IS THE DEFAULT STATE, deliberately. Every slide ships
   visible and the track is a horizontal scroll-snap scroller, so
   with JavaScript off (or before article-carousel.js runs) the
   component is a swipeable filmstrip that already works on touch —
   which is how most phones will use it anyway. In that state each
   caption is still inside its own slide, directly under its own
   image, so nothing is orphaned.

   article-carousel.js then LIFTS the captions out of the slides
   into .art-carousel-caps below the controls and shows one at a
   time. That is the only way to get image -> controls -> text in
   that order while keeping the no-JS document sane: a caption
   authored outside the slide would have nothing tying it to its
   image without a script, and a caption left inside it can never
   have the controls between the two.
   ============================================================ */

.art-carousel {
    margin: 0 0 22px;
    border: 1px solid var(--border-light);
    border-radius: 10px;
    background: var(--surface-alt);
    /* clips the image's top corners to the card radius */
    overflow: hidden;
}

/* Full-bleed on the phone, the same trade .art-figure makes — the
   screenshots are the point and the gutters are not. Side borders and
   the radius come off with the gutters; the top and bottom hairlines
   stay, so the card still reads as one band. */
@media (max-width: 767.98px) {
    .art-carousel {
        margin-left: calc(var(--gutter) * -1);
        margin-right: calc(var(--gutter) * -1);
        border-left: 0;
        border-right: 0;
        border-radius: 0;
    }
}

/* ---------- the track ---------- */
.art-carousel-track {
    display: flex;
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    scroll-behavior: smooth;
    /* the scrollbar is the no-JS affordance; once enhanced the
       arrows and dots take over and it only adds noise */
    scrollbar-width: thin;
}
.art-carousel[data-enhanced] .art-carousel-track {
    scrollbar-width: none;
    -ms-overflow-style: none;
}
.art-carousel[data-enhanced] .art-carousel-track::-webkit-scrollbar { display: none; }

@media (prefers-reduced-motion: reduce) {
    .art-carousel-track { scroll-behavior: auto; }
}

.art-carousel-slide {
    flex: 0 0 100%;
    min-width: 0;
}

.art-carousel-slide img {
    display: block;
    width: 100%;
    height: auto;
    background: var(--surface-alt);
}

/* ---------- controls: centred, directly under the image ---------- */
.art-carousel-chrome { display: none; }
.art-carousel[data-enhanced] .art-carousel-chrome {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 14px;
    padding: 9px var(--gutter);
    border-top: 1px solid var(--border-light);
    /* the counter is pinned to the right edge and must not drag the
       dots off centre — see .art-carousel-count */
    position: relative;
}

.art-carousel-dots {
    display: flex;
    gap: 7px;
    flex-wrap: wrap;
    justify-content: center;
    min-width: 0;
}
.art-carousel-dot {
    width: 7px;
    height: 7px;
    padding: 0;
    border: 0;
    border-radius: 50%;
    background: var(--border);
    cursor: pointer;
    transition: background .18s ease, transform .18s ease;
}
.art-carousel-dot[aria-current="true"] {
    background: var(--accent);
    transform: scale(1.35);
}
.art-carousel-dot:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
}

.art-carousel-nav { display: contents; }
.art-carousel-btn {
    width: 28px;
    height: 28px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border: 1px solid var(--border-light);
    border-radius: 50%;
    background: var(--surface);
    color: var(--text-muted);
    cursor: pointer;
    font-size: 12px;
    line-height: 1;
    flex: none;
    transition: color .18s ease, border-color .18s ease;
}
.art-carousel-btn:hover:not(:disabled) {
    color: var(--accent-dark);
    border-color: var(--accent);
}
.art-carousel-btn:disabled { opacity: .3; cursor: default; }
.art-carousel-btn:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
}
/* display:contents on .art-carousel-nav puts both buttons directly into
   the chrome's flex row so they sit either side of the dots instead of
   as a pair beside them. BOTH need an explicit order: the DOM keeps the
   two buttons adjacent (and before the dots) so that Tab reaches prev
   then next, and without an order on the second one the row lays out as
   prev-next-dots and the dots sit off centre. */
.art-carousel-nav .art-carousel-btn:first-child { order: -1; }
.art-carousel-nav .art-carousel-btn:last-child { order: 1; }

/* Pinned right rather than in the flow: in the flow it is a third flex
   child and the dots centre against IT, not against the card. Mono so
   the width does not jitter as the index changes. */
.art-carousel-count {
    position: absolute;
    right: var(--gutter);
    top: 50%;
    transform: translateY(-50%);
    font-family: var(--art-font-mono);
    font-size: 11px;
    color: var(--text-muted);
}

/* Under ~420px the counter starts crowding the arrows. It is the
   aria-live region, so it is clipped rather than display:none —
   display:none would stop it being announced at all. */
@media (max-width: 419.98px) {
    .art-carousel-count {
        position: absolute;
        width: 1px; height: 1px;
        padding: 0; margin: -1px;
        overflow: hidden;
        clip-path: inset(50%);
        white-space: nowrap;
    }
}

/* ---------- the explanation, under the controls ---------- */
.art-carousel-caps {
    padding: 12px var(--gutter) 14px;
    border-top: 1px solid var(--border-light);
    background: var(--surface);
}
/* Before the script lifts them out, captions sit inside their slide and
   need the same padding but no band of their own. */
.art-carousel-slide .art-carousel-cap {
    padding: 12px var(--gutter) 14px;
    border-top: 1px solid var(--border-light);
    background: var(--surface);
}
.art-carousel-cap[hidden] { display: none; }

.art-carousel-name {
    font-size: 14px;
    font-weight: 700;
    margin-bottom: 2px;
}
.art-carousel-role {
    font-size: 12px;
    font-weight: 600;
    color: var(--accent);
    margin-bottom: 6px;
}
.art-carousel-text {
    font-size: 13px;
    line-height: 1.65;
    color: var(--text-muted);
    margin: 0;
}

@media (min-width: 768px) {
    .art-carousel-caps,
    .art-carousel-slide .art-carousel-cap { padding: 14px 16px 16px; }
    .art-carousel[data-enhanced] .art-carousel-chrome { padding: 9px 16px; }
    .art-carousel-count { right: 16px; }
    .art-carousel-name { font-size: 15px; }
    .art-carousel-text { font-size: 13.5px; }
}

/* The lightbox that used to live here is now
   css/v2/article/lightbox.css, loaded by all four article shells. It moved
   because it stopped being a carousel component: every article image on
   every shell is clickable now, and a deck is just one caller of it. The
   carousel keeps only the part that is genuinely its own — handing its
   slides and their captions over (see article-carousel.js), which is why
   there is no .art-carousel[data-zoomable] rule left here either. The
   zoom-in cursor is keyed on img[data-zoomable] in lightbox.css, and the
   script sets that attribute on whatever it claims, deck or not. */
