/* Plucky Works marketing page layout, loaded only by marketingbase.html.
   Design tokens and the brand font come from marketing_chrome.css, which is
   always loaded first. Design spec:
   docs/superpowers/specs/2026-08-02-marketing-site-visual-design.md */
* { box-sizing: border-box; }
/* Sticky-footer shell: on short pages (demo confirmation) main absorbs the
   leftover viewport height, so the footer stays a compact strip at the bottom
   instead of the page ending mid-viewport with the ground color pooling into
   the footer. Marketing pages only; the Bootstrap blog pages load chrome CSS
   but not this file. */
body { margin: 0; font-family: var(--pw-font); color: var(--pw-text); background: var(--pw-ground); font-size: 16.5px; line-height: 1.65; overflow-x: clip; min-height: 100vh; display: flex; flex-direction: column; }
.wrap { max-width: 1120px; margin: 0 auto; padding: 0 24px 64px; }
main.wrap { flex: 1 0 auto; width: 100%; }
/* The ink footer sits flush on every marketing page: a closing band lands
   right on the footer hairline, and a plain ending keeps its breathing room
   from .wrap's own bottom padding. (The 72px chrome default is for the blog
   pages, which have no .wrap padding of their own.) */
body > footer.sitefoot { flex-shrink: 0; margin-top: 0; }
/* The nav is sticky, so in-page anchors need clearance or they land underneath it. */
[id] { scroll-margin-top: 96px; }
/* Line breaking. Headings balance: a heading in a narrow card column otherwise
   breaks wherever the line happens to run out ("Explore new revenue /
   opportunities"), which reads as a mistake rather than a line. Balancing
   evens the lines instead. Prose gets `pretty`, which only reflows the last
   couple of lines to clear a one-word orphan ("...in print or / online."). */
h1, h2, h3 { text-wrap: balance; }
p, ul.plain li { text-wrap: pretty; }
/* Leads and subs are decks, not body copy: 2-4 lines sitting under a heading.
   Left to `pretty` they run the full 68ch measure and then end on a stub of a
   line (13-41% of the longest), which is the wrapping that reads as broken.
   Balancing spreads them over even lines, which also pulls the used measure
   from ~75 characters down toward the 45-75 range. Chromium stops balancing
   past 6 lines, so a lead that ever grows that long degrades to `pretty`. */
.lead, .sub { text-wrap: balance; }
h1 { color: var(--pw-ink); font-size: 46px; font-weight: 800; letter-spacing: -0.025em; line-height: 1.1; margin: 0 0 18px; }
h2 { color: var(--pw-ink); font-size: 30px; font-weight: 800; letter-spacing: -0.015em; line-height: 1.15; margin: 0 0 16px; }
h3 { color: var(--pw-ink); font-size: 21px; font-weight: 800; line-height: 1.25; margin: 0 0 10px; }
p { margin: 0 0 12px; }
main a { color: var(--pw-red-text); font-weight: 700; text-decoration: none; }
main a:hover { color: var(--pw-red-hover); text-decoration: underline; }
/* No italics: Manrope has no italic face, and muted color alone carries the aside tone. */
.sub { font-style: normal; font-size: 14px; font-weight: 500; color: var(--pw-muted); margin: 0 0 12px; }
.lead { font-size: 18px; margin: 0 0 20px; }
/* Prose caps at a readable measure so no line runs the full 1120px column. */
.lead, .sub, .hero p, .ztext p, .qa .a, .qa ul.plain, .card > p { max-width: 68ch; }
/* Opt a lead paragraph out of the readable-measure cap to span the full section width. */
.lead.lead-full { max-width: none; }
/* Sections carry the page's vertical rhythm: the gap between two sections always reads larger than any gap inside one. */
.section { margin-top: 64px; } .section:first-child { margin-top: 0; } .section > :last-child { margin-bottom: 0; } .section > :first-child { margin-top: 0; }
.hero { display: grid; grid-template-columns: 1.05fr 0.95fr; gap: 48px; align-items: center; }
.hero.single { display: block; }
.hero > :last-child, .herotext > :last-child { margin-bottom: 0; }
.narrow { max-width: 620px; }
/* Single centered column for section content that has no second column beside
   it: an uncentered .narrow block strands the right half of a wide viewport, so
   a lone card reads as a grid that lost its other cards. Centering the heading
   and the card together makes the whitespace symmetric and deliberate. Text
   inside stays left-aligned. */
.single-col { max-width: 620px; margin-left: auto; margin-right: auto; }
main :focus-visible { outline: 2px solid var(--pw-ink); outline-offset: 2px; }
/* --- cards and grids --- */
.card { background: var(--pw-surface); border: 0; border-radius: var(--pw-radius-card); box-shadow: var(--pw-shadow-card); padding: 24px; margin-bottom: 16px; display: flex; flex-direction: column; }
.card > :last-child { margin-bottom: 0; }
.card h3 { font-size: 17px; }
.grid { display: grid; gap: 20px; } .g2 { grid-template-columns: 1fr 1fr; } .g3 { grid-template-columns: 1fr 1fr 1fr; } .g4 { grid-template-columns: 1fr 1fr 1fr 1fr; } .grid .card { margin-bottom: 0; }
/* Availability chip beside a title. The fill state carries the meaning:
   solid ink = shipped, hollow outline = pre-release, so no color leaves the
   neutral palette. Every badge site sits on band-white, where the old ground
   fill vanished; the border is what makes the hollow chip read as a chip.
   Transparent fill keeps --pw-muted text at 7:1 on white. The solid variant
   keeps the same 1px border (ink-on-ink) so both chips are the same height.
   letter-spacing must be reset: the h1's -0.025em inherits as its computed
   value (-1.15px at 46px), which at 13px all but deletes the word space. */
.status-badge { border: 1px solid var(--pw-dark-body); border-radius: 999px; background: transparent; color: var(--pw-muted); display: inline-block; font-size: 13px; line-height: 1.5; font-weight: 700; letter-spacing: normal; padding: 2px 10px; margin-left: 8px; vertical-align: 3px; white-space: nowrap; }
.status-badge.available { background: var(--pw-ink); border-color: var(--pw-ink); color: #fff; }
/* Inside home-card titles the chip drops onto its own line: "Assignments"
   plus the chip overflows a g4 column, and one wrapped chip in a row of four
   inline ones reads as a mistake. Below the title, all four align. */
.card h3 .status-badge { display: block; width: fit-content; margin: 6px 0 0; }
/* --- placeholders as quiet browser-frame cards --- */
.imgbox { position: relative; overflow: hidden; background: var(--pw-fill); border: 0; border-radius: var(--pw-radius-frame); box-shadow: var(--pw-shadow-card); color: var(--pw-text); font-style: normal; font-size: 13px; padding: 44px 16px 16px; min-height: 220px; display: flex; align-items: center; justify-content: center; text-align: center; margin-top: 16px; }
.imgbox::before { content: ""; position: absolute; top: 0; left: 0; right: 0; height: 28px; background: var(--pw-surface); border-bottom: 1px solid var(--pw-fill); }
.imgbox::after { content: ""; position: absolute; top: 11px; left: 14px; width: 6px; height: 6px; border-radius: 50%; background: var(--pw-dark-body); box-shadow: 12px 0 0 var(--pw-dark-body), 24px 0 0 var(--pw-dark-body); }
.hero-visual { min-height: 320px; margin-top: 0; box-shadow: var(--pw-shadow-float); }
.zart.imgbox { margin-top: 0; box-shadow: var(--pw-shadow-float); }
/* Hero tool tiles (home): four equal icon-and-name cards, one per tool, so
   the four-tool structure reads before any body copy. Greyscale placeholder
   treatment until a real icon set exists: ground tiles ringed in fill, fill
   icon squares, muted glyphs, ink names. */
.hero-gallery { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
.tool-tile { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 14px; padding: 36px 16px; background: var(--pw-ground); border-radius: var(--pw-radius-card); box-shadow: inset 0 0 0 1px var(--pw-fill); }
.tool-icon { display: flex; align-items: center; justify-content: center; width: 72px; height: 72px; border-radius: 18px; background: var(--pw-fill); }
.tool-icon img { display: block; width: 40px; height: 40px; }
.tool-name { font-weight: 800; font-size: 19px; letter-spacing: -0.01em; color: var(--pw-ink); }
/* Mini placeholders inside cards: flat fill, no frame chrome. */
.grid .card > .imgbox { margin-top: auto; min-height: 160px; box-shadow: none; padding: 16px; background: var(--pw-ground); }
/* A card whose preview image sits below its link: the .actions row takes the
   free space instead of the image, so the link pins to the foot of the text
   block above the image and the links line up across the row. */
.grid .card > .actions + .imgbox { margin-top: 16px; }
.grid .card > .imgbox::before, .grid .card > .imgbox::after { display: none; }
.photo { display: block; width: 100%; height: auto; border-radius: var(--pw-radius-frame); }
.imgbox + .byline, .photo + .byline { margin-top: 10px; }
/* Actions sit at the foot of a card, so the links line up across a row of cards. */
.actions { display: flex; flex-wrap: wrap; gap: 10px; margin-top: auto; padding-top: 14px; }
.actions .cta { margin: 0; }
/* --- z rows: text sits directly on the band, art floats --- */
.zrow { display: grid; grid-template-columns: 1fr 1fr; gap: 40px; align-items: center; margin-top: 32px; }
.zrow .imgbox { margin-top: 0; }
.zrow .card, .ztext.card { background: transparent; border: 0; box-shadow: none; padding: 0; margin-bottom: 0; display: block; }
.zrow.flip .ztext { order: 2; } .zrow.flip .zart { order: 1; }
.zrow.wide-text { grid-template-columns: 1.6fr 1fr; }
/* Stacked z rows need more air between them than the 40px gap inside a row, or
   one row's art reads as belonging to the next row's text. This exceeds the
   64px section margin, which is fine here: every section that stacks z rows is
   bounded by banded sections, so a section boundary is carried by a background
   change plus the band's own 56/64px padding (~120px of air), not by the margin
   alone. Revisit if a plain section ever stacks z rows next to another plain one. */
.zrow + .zrow { margin-top: 72px; }
.zrow + .card, .grid + .card, .grid + p, .grid + .cta { margin-top: 24px; }
/* --- lists: red dot bullets (decorative, non-text) --- */
ul.plain { list-style: none; margin: 8px 0 14px; padding-left: 0; }
ul.plain li { position: relative; padding-left: 18px; margin-bottom: 8px; max-width: 66ch; }
ul.plain li::before { content: ""; position: absolute; left: 0; top: 0.58em; width: 6px; height: 6px; border-radius: 50%; background: var(--pw-red); }
/* --- quotes --- */
.quote p:first-child { color: var(--pw-ink); font-size: 17px; font-weight: 600; line-height: 1.55; }
.byline { color: var(--pw-muted); font-size: 13px; font-weight: 600; }
.headshot { width: 48px; height: 48px; border-radius: 50%; object-fit: cover; display: block; margin-top: 14px; }
.quote .headshot + .byline { margin-top: 8px; }
.card > .headshot:first-child { margin-top: 0; margin-bottom: 12px; }
/* Team bio cards. Each one stacks a bold name, a lighter role line, the disclosure
   toggle, then the bio itself. The identity block is two lines in every card, so
   the three toggles land on one baseline without being pinned to the card foot --
   which is the point: nothing above the toggle changes when a bio opens, so the
   toggle holds its place instead of sliding as the row grows. */
/* Team headshots run 1.5x the 48px avatar the quote blocks use: these are the
   subject of the card, not a byline attached to someone else's words. */
.bio-card .headshot { width: 72px; height: 72px; }
.bio-card h3 { margin-bottom: 4px; }
.bio-card .role { color: var(--pw-muted); font-size: 14px; font-weight: 500; margin: 0 0 12px; }
/* Between the 760px single-column switch and ~850px the three columns are narrow
   enough that a longer role wraps to a second line, which would drop that card's
   toggle 23px below the other two. Reserving the second line across the band holds
   the baseline; wider than that every role fits on one line, so no space is held
   back. A browser without `lh` takes the px fallback. */
@media (min-width: 761px) and (max-width: 850px) {
    .bio-card .role { min-height: 46px; min-height: 2lh; }
}
/* The toggle changes content rather than navigating, so it is a button, but it
   borrows the light-band link styling above so it reads as one instead of competing
   with the name. align-self keeps it hugging its label in the flex-column card. */
.bio-toggle { align-self: flex-start; padding: 0; border: 0; background: none; font-family: inherit; font-size: inherit; font-weight: 700; color: var(--pw-red-text); cursor: pointer; }
.bio-toggle:hover { color: var(--pw-red-hover); text-decoration: underline; }
/* The bio reads a step down from body copy, the size the card was already set in
   before the placeholder treatment came off it. */
.bio-card .bio { font-size: 15px; line-height: 1.6; margin: 12px 0 0; }
/* --- pricing --- */
.price { color: var(--pw-ink); font-size: 20px; font-weight: 800; margin: 0 0 12px; }
/* Visually-hidden text: keeps the annual rate available to screen readers and to
   the no-JS render without showing both billing periods at once. */
.visually-hidden { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
/* Elements Alpine reveals once it initializes; hidden until then so the annual
   note never flashes on load. */
[x-cloak] { display: none !important; }
/* --- pricing plans (comparison cards + collaborative estimator) --- */
/* Monthly/Annual segmented control: an ink fill marks the active period so red
   stays reserved for the featured-plan ring and the CTA. */
.plan-toggle { display: inline-flex; gap: 4px; background: var(--pw-fill); border-radius: 999px; padding: 4px; margin: 0 0 20px; }
.plan-toggle button { font-family: inherit; font-size: 14px; font-weight: 700; color: var(--pw-ink); background: none; border: 0; border-radius: 999px; padding: 8px 18px; cursor: pointer; }
.plan-toggle button.is-active { background: var(--pw-ink); color: #fff; }
.plan { position: relative; }
/* The featured plan takes the 2px inset red ring the design spec reserves for it. */
.plan.featured { box-shadow: inset 0 0 0 2px var(--pw-red), var(--pw-shadow-card); }
.plan-tag { position: absolute; top: -12px; left: 24px; background: var(--pw-red); color: #fff; font-size: 12px; font-weight: 800; letter-spacing: 0.04em; text-transform: uppercase; border-radius: 999px; padding: 3px 12px; }
.plan .price .sub { display: block; margin-top: 2px; }
/* Estimator: the range accent matches the brand red; the two output boxes sit on
   the ground fill so they read as results inside the white card. */
.estimator input[type="range"] { width: 100%; accent-color: var(--pw-red); margin: 8px 0 14px; }
.estimator #bulk-discount-label { color: var(--pw-ink); font-weight: 800; }
.estimator .estimate { background: var(--pw-ground); border-radius: var(--pw-radius-frame); padding: 16px; }
.estimator .estimate > :last-child { margin-bottom: 0; }
.plan-compare .sub a, .estimator label strong { color: var(--pw-ink); }
/* --- faq --- */
.qa { border-top: 1px solid var(--pw-fill); padding: 20px 0; }
.qa .q { color: var(--pw-ink); font-weight: 800; font-size: 17px; margin: 0 0 8px; }
.qa .a { margin: 0 0 10px; } .qa .a:last-child { margin-bottom: 0; }
/* --- full-bleed bands: escape the 1120px .wrap without changing the template structure --- */
.band-white, .band-dark { margin-inline: calc(50% - 50vw); padding-inline: calc(50vw - 50%); }
.section.band-white { background: var(--pw-surface); padding-top: 56px; padding-bottom: 64px; }
.section.band-dark { background: var(--pw-ink); color: var(--pw-dark-body); padding-top: 56px; padding-bottom: 64px; }
.band-dark h2, .band-dark h3 { color: #fff; }
.band-dark p, .band-dark .sub { color: var(--pw-dark-body); }
.band-dark a { color: #fff; text-decoration: underline; }
.band-dark a:hover { color: var(--pw-dark-body); }
/* On the dark band the CTA inverts (a red fill only reaches 2.5:1 against the ink band).
   The CTA is not a plain link, so it opts back out of the underline and bumps to the
   800 weight the spec calls for on this variant. */
.band-dark .cta, .band-dark .cta.todo { background: var(--pw-surface); color: var(--pw-red); opacity: 1; text-decoration: none; font-weight: 800; }
.band-dark .cta:hover { color: var(--pw-red); background: var(--pw-surface); }
.band-dark .cta.todo { opacity: 0.55; cursor: not-allowed; }
.band-dark :focus-visible { outline-color: #fff; }
/* Bands are flush color blocks: their internal padding carries the spacing, so the
   base section margin must not stack on top of it when one band follows another
   (fix from Task 4 review). A band that follows PLAIN content still needs the
   standard inter-section gap, or the plain section's last line sits flush against
   the band's colored edge (fix from final review). */
.section + .section.band-white, .section + .section.band-dark { margin-top: 64px; }
.section.band-white + .section.band-white,
.section.band-white + .section.band-dark,
.section.band-dark + .section.band-white,
.section.band-dark + .section.band-dark { margin-top: 0; }
/* When a page's last section is a color band (dark closing band, or the white
   band the pricing and demo pages end on), let the band's own color run into
   .wrap's bottom padding so the band lands right on the footer's top edge
   instead of leaving a hollow ground-colored gap that reads as a stray band. */
.wrap > .section.band-dark:last-child, .wrap > .section.band-white:last-child { margin-bottom: -64px; }
/* Short pages (demo confirmation): the sticky-footer shell leaves spare
   viewport height inside main; when the page ends on a white band, the band
   absorbs that height so the white hero runs all the way to the footer
   instead of ground color pooling beneath it. Tall pages are unaffected:
   there is no spare height. */
main.wrap:has(> .section.band-white:last-child) { display: flex; flex-direction: column; }
main.wrap > .section.band-white:last-child { flex: 1 0 auto; }
/* Uppercase micro label for the social-proof strip. */
.micro { font-size: 13px; font-weight: 800; letter-spacing: 0.1em; text-transform: uppercase; color: var(--pw-muted); text-align: center; margin: 0 0 14px; }
/* Eyebrow kicker above an audience page h1: names the audience the nav item
   promised, so the page orients the reader without giving up its benefit-led
   headline. Same treatment as .micro but left-aligned with the hero text, and
   the tight margin binds it to the h1 rather than floating between sections. */
.eyebrow { font-size: 13px; font-weight: 800; letter-spacing: 0.1em; text-transform: uppercase; color: var(--pw-muted); margin: 0 0 10px; }
#support-plans { scroll-margin-top: 90px; }
@media (max-width: 359px) {
    #support-plans { scroll-margin-top: 120px; }
}
/* The logo strip placeholder stays short and quiet. */
.imgbox.logo-strip { min-height: 120px; }
/* Jump list: an at-a-glance map of the question groups below it. */
.jump { display: flex; flex-wrap: wrap; gap: 10px; list-style: none; margin: 0 0 8px; padding: 0; }
.jump a { display: inline-block; background: var(--pw-surface); color: var(--pw-ink); font-size: 14px; font-weight: 700; border-radius: 999px; padding: 7px 16px; box-shadow: inset 0 0 0 1px var(--pw-fill); }
.jump a:hover { color: var(--pw-ink); background: var(--pw-ground); text-decoration: none; }
@media (max-width: 1000px) { .g4 { grid-template-columns: 1fr 1fr; } }
@media (max-width: 760px) {
    .hero, .g2, .g3, .g4, .zrow, .zrow.wide-text { grid-template-columns: 1fr; }
    .hero { display: block; }
    .hero .hero-visual { margin-top: 20px; }
    /* The tiles keep their two-by-two shape on mobile, just tighter. */
    .hero-gallery { gap: 12px; margin-top: 20px; }
    .tool-tile { padding: 24px 12px; gap: 10px; }
    .zrow.flip .ztext, .zrow.flip .zart { order: 0; }
    .section { margin-top: 44px; }
    .section + .section.band-white, .section + .section.band-dark { margin-top: 44px; }
    .zrow + .zrow { margin-top: 56px; }
    h1 { font-size: 32px; }
    h2 { font-size: 25px; }
}
/* --- demo request form --- */
/* The demo pages put the form/panel card inside the white hero band (the
   product-page hero treatment); the card needs its own gap under the lead. */
.hero.single .demo-form, .hero.single .demo-panel { margin-top: 36px; }
.demo-form .field { margin: 0 0 18px; border: 0; padding: 0; }
.demo-form .field > label, .demo-form .field > legend { display: block; font-weight: 700; color: var(--pw-ink); padding: 0; margin: 0 0 6px; max-width: 68ch; }
.demo-form input[type="text"], .demo-form input[type="email"], .demo-form textarea { width: 100%; padding: 10px 12px; border: 1.5px solid var(--pw-fill); border-radius: 8px; background: var(--pw-surface); color: var(--pw-text); font-family: var(--pw-font); font-size: 15px; }
.demo-form textarea { min-height: 96px; resize: vertical; }
/* Option rows: both the hand-rendered .choice labels and Django's own
   RadioSelect/CheckboxSelectMultiple output (labels nested in divs). The grid
   gives wrapped label text a hanging indent clear of its input. label.choice
   (not bare .choice) so this outranks the .field > label question-label rule
   above for the interests checkboxes, which sit directly in their fieldset. */
.demo-form label.choice, .demo-form .field div label { display: grid; grid-template-columns: 16px 1fr; gap: 0 8px; align-items: start; font-weight: 500; color: var(--pw-text); margin: 0 0 8px; }
.demo-form input[type="checkbox"], .demo-form input[type="radio"] { justify-self: start; margin: 6px 0 0; accent-color: var(--pw-red); }
.demo-form .field-error { color: var(--pw-red-text); font-size: 14px; font-weight: 700; margin: 0 0 6px; }
.demo-form .form-error-summary { border: 1.5px solid var(--pw-red); border-radius: 8px; color: var(--pw-red-text); font-size: 15px; font-weight: 700; padding: 10px 14px; margin: 0 0 18px; }
.demo-form h2 { font-size: 24px; margin-top: 28px; }
.demo-form .cta { margin-top: 20px; }
