/*
 * Stylesheet for the public marketing page (client/public/landing.html).
 *
 * WHY THIS IS AN EXTERNAL FILE, NOT AN INLINE <style> ELEMENT
 * ----------------------------------------------------------
 * server/middleware/securityHeaders.ts sends
 *   style-src-elem 'self'
 * and the report-only inventory added for #156 measured this page's inline
 * <style> element as a style-src-elem violation on every anonymous visit
 * (#536 item 1). Served from a file it is same-origin, so 'self' covers it
 * and the violation is gone. Same reasoning as client/public/landing.js,
 * which moved out of an inline <script> for script-src 'self' — do not move
 * this back inline, and do not add 'unsafe-inline' to style-src-elem to make
 * an inline version work.
 *
 * NO style="" ATTRIBUTES IN THE PAGE EITHER. style-src-attr is 'none' (PR
 * #539 removed the last ones). Anything that would have been an inline style
 * is a class here: .why-close, .cmp-head, .cmp-wrap and .price-cta replace
 * the four style="" attributes in the #1069 draft.
 *
 * Rebuilt for #1069 from the draft the owner approved on 26 September 2026.
 * One deliberate look: the public page is light, in the brand's teal and
 * periwinkle. It is a public marketing page, outside the app's theming
 * (#1068), so its colours are literal here on purpose.
 */
:root {
  color-scheme: light;
  --teal: #1A6D7E; --teal-dark: #12333B; --teal-deep: #0D262C; --blue: #5371FF; --blue-btn: #4660D8;
  --tint: #EAF1F2; --tint2: #F4F7F5; --paper: #FBFBF9; --ink: #17211F; --ink-soft: #4B5957; --line: #C9D6D3;
  --ok: #2F6B45; --ok-bg: #E4F1E8; --due: #8A5A0B; --due-bg: #FBF0DA; --over: #A33A2E; --over-bg: #F8E4E1;
  --serif: "Source Serif 4", Georgia, serif; --sans: "IBM Plex Sans", Arial, sans-serif; --mono: "IBM Plex Mono", "Courier New", monospace;
}
* { box-sizing: border-box; }
html { scroll-behavior: smooth; }
body { margin: 0; background: var(--paper); color: var(--ink); font-family: var(--sans); line-height: 1.55; -webkit-font-smoothing: antialiased; }
img, svg { display: block; max-width: 100%; }
a { color: inherit; }
a:focus-visible, button:focus-visible, input:focus-visible, textarea:focus-visible { outline: 2px solid var(--blue); outline-offset: 2px; }
.wrap { max-width: 1180px; margin: 0 auto; padding-inline: 24px; }
.eyebrow { font-family: var(--mono); font-size: 12.5px; letter-spacing: .14em; text-transform: uppercase; color: var(--teal); font-weight: 500; margin: 0 0 12px; }
h1, h2, h3 { font-family: var(--serif); color: var(--teal-deep); margin: 0; font-weight: 600; text-wrap: balance; }
h1 { font-size: clamp(36px, 5vw, 60px); line-height: 1.05; font-weight: 700; letter-spacing: -.01em; }
h2 { font-size: clamp(28px, 3.3vw, 40px); line-height: 1.12; }
h3 { font-size: 19px; line-height: 1.3; }
p { margin: 0; }
section { padding-block: 84px; }
.lead { font-size: 18px; color: var(--ink-soft); max-width: 44rem; margin-top: 16px; }
/* Anchored sections land below the sticky header rather than under it. */
section[id] { scroll-margin-top: 68px; }
.sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }

/* ---------- nav ---------- */
.nav { position: sticky; top: env(safe-area-inset-top, 0px); z-index: 10; background: rgb(251 251 249 / .94); backdrop-filter: blur(6px); border-bottom: 1px solid var(--line); }
.nav .wrap { display: flex; align-items: center; gap: 24px; height: 68px; }
.brand { display: flex; align-items: center; text-decoration: none; flex: 0 1 auto; min-width: 0; }
/* A horizontal lockup made from the logo artwork (#1069 item 11): the
   stacked logo at nav height left the wordmark small and faint. */
.brand-logo { height: 44px; width: auto; }
.links { display: flex; gap: 22px; margin-left: auto; font-size: 14.5px; font-weight: 500; color: var(--ink-soft); }
.links a { text-decoration: none; }
.links a:hover { color: var(--teal); }
.btn { display: inline-flex; align-items: center; justify-content: center; height: 42px; padding: 0 18px; border-radius: 6px; font: 600 14.5px var(--sans); text-decoration: none; border: 1.5px solid transparent; white-space: nowrap; cursor: pointer; }
.btn.pri { background: var(--blue-btn); color: #fff; }
.btn.pri:hover { background: #3E56D6; }
.btn.pri:disabled { opacity: .7; cursor: default; }
.btn.ghost { border-color: var(--teal); color: var(--teal); background: transparent; }
.nav .btns { display: flex; gap: 10px; }
@media (max-width: 1060px) { .links { display: none; } .nav .btns { margin-left: auto; } }
/* Phones keep "Log in" beside "Start free trial" at every width, as a
   compact text link rather than a second button, so a returning customer is
   never left with only the trial button. Up to 560px the brand is the
   "landholder connect" wordmark on its own, without the LHC square (the
   picture source in landing.html), so the three fit at their true
   proportions. Below 360px even that is too wide with the full button
   label, so the button reads "Free trial" there; the wordmark is never
   shrunk or dropped. */
.nav .label-short { display: none; }
@media (max-width: 560px) {
  .nav .wrap { gap: 10px; padding-inline: 16px; }
  .brand { flex: 0 0 auto; }
  .brand-logo { height: 32px; }
  .nav .btns { gap: 4px; flex: 0 0 auto; align-items: center; }
  .nav .btn { padding: 0 12px; font-size: 14px; }
  .nav .btn.ghost { border-color: transparent; padding: 0 8px; text-decoration: underline; text-underline-offset: 3px; }
}
@media (max-width: 359px) {
  .nav .label-long { display: none; }
  .nav .label-short { display: inline; }
}

/* ---------- hero ---------- */
.hero { padding-block: 72px 64px; }
.hero .wrap { display: grid; grid-template-columns: minmax(0, 1.05fr) minmax(0, .95fr); gap: 48px; align-items: center; }
.hero .sub { font-size: 19px; color: var(--ink-soft); margin-top: 20px; max-width: 34rem; }
.hero .cta { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 28px; }
.facts { display: flex; flex-wrap: wrap; gap: 8px 18px; margin-top: 22px; font-family: var(--mono); font-size: 12.5px; letter-spacing: .08em; text-transform: uppercase; color: var(--teal); }
.facts span + span::before { content: "·"; margin-right: 18px; color: var(--line); }
.bracket { position: relative; }
.bracket::before, .bracket::after { content: ""; position: absolute; width: 22px; height: 22px; border: 2px solid var(--teal); pointer-events: none; }
.bracket::before { top: -7px; left: -7px; border-right: none; border-bottom: none; }
.bracket::after { bottom: -7px; right: -7px; border-left: none; border-top: none; }
.hero-bracket { padding: 34px; }
@media (max-width: 900px) {
  .hero .wrap { grid-template-columns: 1fr; }
  .hero-visual { order: -1; max-width: 26rem; }
}

/* ---------- problem ---------- */
.problem { background: #fff; border-block: 1px solid var(--line); }
.problem .grid { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 48px; margin-top: 36px; }
.plist { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; }
.plist li { padding: 16px 0; border-top: 1px solid var(--line); display: grid; grid-template-columns: 2.2rem 1fr; gap: 10px; }
.plist li:last-child { border-bottom: 1px solid var(--line); }
.plist .n { font-family: var(--mono); font-size: 13px; color: var(--teal); padding-top: 3px; }
.plist h3 { font-size: 18px; margin-bottom: 4px; }
.plist p { color: var(--ink-soft); font-size: 15.5px; }
.cost { background: var(--teal-deep); color: #DCE8E6; padding: 28px; display: flex; flex-direction: column; gap: 18px; }
.cost .eyebrow { color: #8FC3C9; margin: 0; }
.cost h3 { color: #fff; font-size: 18px; margin-bottom: 3px; }
.cost p { font-size: 15px; color: #BFD2CF; }
.cost .note { font-style: italic; font-family: var(--serif); font-size: 17px; color: #fff; border-top: 1px solid rgb(255 255 255 / .15); padding-top: 16px; }
@media (max-width: 900px) { .problem .grid { grid-template-columns: 1fr; } }

/* ---------- data model ---------- */
.flow { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 0; margin-top: 40px; border: 1px solid var(--line); background: #fff; }
.flow > div { padding: 22px 20px; border-right: 1px solid var(--line); position: relative; }
.flow > div:last-child { border-right: 0; }
.flow .k { font-family: var(--mono); font-size: 12px; color: var(--teal); letter-spacing: .08em; }
.flow h3 { margin: 6px 0 6px; }
.flow p { font-size: 15px; color: var(--ink-soft); }
.flow > div:not(:last-child)::after { content: ""; position: absolute; right: -7px; top: 30px; width: 12px; height: 12px; background: #fff; border-top: 1px solid var(--line); border-right: 1px solid var(--line); transform: rotate(45deg); }
.under { margin-top: 14px; display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 14px; }
.under > div { background: var(--tint); border: 1px solid var(--line); padding: 16px 18px; font-size: 15px; color: var(--ink-soft); }
.under b { color: var(--teal-deep); }
@media (max-width: 900px) { .flow { grid-template-columns: 1fr 1fr; } .flow > div:nth-child(2) { border-right: 0; } .flow > div:nth-child(-n+2) { border-bottom: 1px solid var(--line); } .flow > div::after { display: none; } .under { grid-template-columns: 1fr; } }
@media (max-width: 520px) { .flow { grid-template-columns: 1fr; } .flow > div { border-right: 0; border-bottom: 1px solid var(--line); } .flow > div:last-child { border-bottom: 0; } }

/* ---------- features ---------- */
.features { background: var(--tint2); border-block: 1px solid var(--line); }
.feat { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 56px; align-items: center; padding-block: 44px; border-top: 1px solid var(--line); }
/* The first row sits under the section heading, so it takes no rule. */
.features .wrap > div:first-child + .feat { border-top: 0; }
.feat.flip .txt { order: 2; }
.feat .txt p { color: var(--ink-soft); font-size: 16.5px; margin-top: 10px; }
.feat ul { margin: 14px 0 0; padding-left: 1.1rem; color: var(--ink-soft); font-size: 15.5px; display: flex; flex-direction: column; gap: 5px; }
.tag { display: inline-block; font-family: var(--mono); font-size: 11.5px; letter-spacing: .1em; text-transform: uppercase; color: var(--blue-btn); margin-bottom: 8px; }
@media (max-width: 900px) { .feat { grid-template-columns: 1fr; gap: 24px; } .feat.flip .txt { order: 0; } }
.vig { background: #fff; border: 1px solid var(--line); border-radius: 8px; box-shadow: 0 1px 2px rgb(13 38 44 / .05), 0 10px 28px rgb(13 38 44 / .07); padding: 18px; font-size: 14px; min-width: 0; }
.vig h4 { margin: 0 0 2px; font: 600 15.5px var(--sans); color: var(--ink); }
.vig .s { color: var(--ink-soft); font-size: 12.5px; }
.vrow { display: flex; justify-content: space-between; align-items: center; gap: 10px; padding: 10px 0; border-top: 1px solid #E3E9E7; }
.vrow:first-of-type { border-top: 0; }
.vrow > div { min-width: 0; }
.pill { font: 600 11.5px var(--sans); padding: 2px 8px; border-radius: 4px; border: 1px solid; white-space: nowrap; }
.pill.ok { color: var(--ok); background: var(--ok-bg); border-color: #B7D8C1; }
.pill.due { color: var(--due); background: var(--due-bg); border-color: #EBCF95; }
.pill.over { color: var(--over); background: var(--over-bg); border-color: #E6B3AC; }
.pill.n { color: var(--teal); background: var(--tint); border-color: var(--line); }
.vhead { display: flex; justify-content: space-between; align-items: baseline; gap: 10px; padding-bottom: 10px; border-bottom: 1px solid #E3E9E7; margin-bottom: 2px; }
.fmt { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 12px; }
.fmt span { font-family: var(--mono); font-size: 12px; border: 1px solid var(--line); background: var(--tint2); padding: 4px 9px; border-radius: 4px; color: var(--teal-deep); }
.small6 { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 28px 36px; margin-top: 36px; padding-top: 36px; border-top: 1px solid var(--line); }
.small6 h3 { font-size: 17px; margin-bottom: 4px; }
.small6 p { color: var(--ink-soft); font-size: 15px; }
@media (max-width: 900px) { .small6 { grid-template-columns: 1fr 1fr; } }
@media (max-width: 560px) { .small6 { grid-template-columns: 1fr; } }

/* ---------- across Australia ---------- */
.states { width: 100%; border-collapse: collapse; font-size: 15px; background: #fff; }
.states th, .states td { text-align: left; padding: 11px 14px; border-bottom: 1px solid var(--line); }
.states thead th { font: 500 12px var(--mono); letter-spacing: .08em; text-transform: uppercase; color: var(--teal); background: var(--tint2); }
.states td:first-child { font-weight: 600; color: var(--teal-deep); }
.yes { color: var(--ok); font-weight: 600; }
.no { color: #5F6B69; }
/* Tables scroll inside their own box, never the page. */
.tablewrap { overflow-x: auto; border: 1px solid var(--line); border-bottom: 0; margin-top: 30px; max-width: 100%; }
.tablewrap .states { min-width: 34rem; }
.fine { margin-top: 12px; font-size: 14px; color: var(--ink-soft); }

/* ---------- AI ---------- */
.ai { background: var(--teal-deep); color: #D5E4E1; }
.ai h2, .ai h3 { color: #fff; }
.ai .eyebrow { color: #8FC3C9; }
.ai .lead { color: #BFD2CF; }
.aigrid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 1px; background: rgb(255 255 255 / .12); border: 1px solid rgb(255 255 255 / .12); margin-top: 36px; }
.aigrid > div { background: var(--teal-deep); padding: 22px; }
.aigrid h3 { font-size: 17px; margin-bottom: 6px; }
.aigrid p { font-size: 15px; color: #BFD2CF; }
.ai .guard { margin-top: 20px; font-size: 15px; color: #BFD2CF; max-width: 50rem; }
@media (max-width: 900px) { .aigrid { grid-template-columns: 1fr 1fr; } }
@media (max-width: 560px) { .aigrid { grid-template-columns: 1fr; } }

/* ---------- security ---------- */
.sec .cols { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 0 28px; margin-top: 36px; border-top: 2px solid var(--teal-deep); }
.sec .cols > div { padding: 20px 0 22px; border-bottom: 1px solid var(--line); }
.sec h3 { font-size: 17px; margin-bottom: 5px; }
.sec p { font-size: 15px; color: var(--ink-soft); }
.sec .cert { margin-top: 22px; font-size: 14.5px; color: var(--ink-soft); background: var(--tint2); border: 1px solid var(--line); padding: 14px 16px; }
@media (max-width: 900px) { .sec .cols { grid-template-columns: 1fr 1fr; } }
@media (max-width: 560px) { .sec .cols { grid-template-columns: 1fr; } }

/* ---------- why not enterprise + comparison ---------- */
.why .two { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 20px; margin-top: 32px; }
.why .two > div { border: 1px solid var(--line); padding: 22px; background: #fff; }
.why .two > div.need { background: var(--tint); border-color: var(--teal); }
.why ul { margin: 12px 0 0; padding-left: 1.1rem; color: var(--ink-soft); display: flex; flex-direction: column; gap: 6px; font-size: 15.5px; }
.why .need ul { color: var(--teal-deep); font-family: var(--serif); font-size: 17px; }
.why .why-close { margin-top: 18px; }
.why .cmp-head { margin-top: 56px; }
.why .cmp-wrap { margin-top: 16px; }
@media (max-width: 800px) { .why .two { grid-template-columns: 1fr; } }
.cmp { width: 100%; border-collapse: collapse; font-size: 15px; background: #fff; min-width: 30rem; }
.cmp th, .cmp td { padding: 11px 14px; border-bottom: 1px solid var(--line); text-align: left; }
.cmp thead th { font: 500 12px var(--mono); letter-spacing: .08em; text-transform: uppercase; color: var(--teal); }
.cmp td:nth-child(2) { background: var(--tint); font-weight: 600; color: var(--teal-deep); }
.cmp thead th:nth-child(2) { background: var(--tint); }

/* ---------- time to value ---------- */
.steps { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 20px; margin-top: 36px; }
.steps > div { border-top: 3px solid var(--teal); padding-top: 14px; }
.steps .t { font: 500 12.5px var(--mono); color: var(--blue-btn); margin-top: 6px; }
.steps p { color: var(--ink-soft); font-size: 15px; margin-top: 4px; }
.steps .num { font: 500 12px var(--mono); color: var(--teal); letter-spacing: .08em; }
.bring { margin-top: 28px; display: grid; grid-template-columns: auto minmax(0, 1fr); gap: 18px; align-items: center; background: #fff; border: 1px solid var(--teal); padding: 20px 22px; }
.bring .ic { width: 44px; height: 44px; border-radius: 50%; background: var(--tint); display: grid; place-items: center; color: var(--teal); font: 600 18px var(--serif); }
.bring p { color: var(--ink-soft); font-size: 15.5px; margin-top: 3px; }
@media (max-width: 900px) { .steps { grid-template-columns: 1fr 1fr; } }
@media (max-width: 520px) { .steps { grid-template-columns: 1fr; } .bring { grid-template-columns: 1fr; } }

/* ---------- pricing ---------- */
.pricing { background: var(--tint2); border-block: 1px solid var(--line); }
.price { display: grid; grid-template-columns: minmax(0, .9fr) minmax(0, 1.1fr); gap: 0; margin-top: 36px; background: #fff; border: 1px solid var(--line); }
.price .l { padding: 30px; border-right: 1px solid var(--line); display: flex; flex-direction: column; gap: 6px; }
.amt { font: 700 64px/1 var(--serif); color: var(--teal-deep); }
.amt small { font: 500 13px var(--mono); letter-spacing: .08em; color: var(--teal); display: block; margin-top: 8px; }
.price .l p { color: var(--ink-soft); font-size: 15.5px; }
.price .price-cta { margin-top: 14px; }
.price .r { padding: 30px; }
.price ul { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: 1fr 1fr; gap: 10px 22px; font-size: 15.5px; }
.price li { padding-left: 1.4em; text-indent: -1.4em; }
.price li::before { content: "✓"; color: var(--ok); font-weight: 700; display: inline-block; width: 1.4em; text-indent: 0; }
.price .fine { margin-top: 20px; }
@media (max-width: 800px) { .price { grid-template-columns: 1fr; } .price .l { border-right: 0; border-bottom: 1px solid var(--line); } .price ul { grid-template-columns: 1fr; } }
@media (max-width: 420px) { .price .l, .price .r { padding: 22px; } .price .btn { white-space: normal; height: auto; min-height: 42px; padding-block: 8px; text-align: center; } }

/* ---------- founder ---------- */
.founder .wrap { display: grid; grid-template-columns: 220px minmax(0, 1fr); gap: 44px; align-items: start; }
.photo { aspect-ratio: 1; max-width: 220px; width: 100%; border-radius: 50%; overflow: hidden; border: 3px solid var(--tint); box-shadow: 0 0 0 1px var(--line); }
.photo img { width: 100%; height: 100%; object-fit: cover; transform: scale(1.4); transform-origin: 52% 36%; }
.founder blockquote { margin: 14px 0 0; font: italic 22px/1.5 var(--serif); color: var(--teal-deep); }
.founder .who { margin-top: 16px; font-size: 15.5px; }
.founder .who b { color: var(--teal-deep); }
.founder .who a { color: var(--blue-btn); font-weight: 600; }
.founder .bio { margin-top: 14px; color: var(--ink-soft); font-size: 15.5px; }
@media (max-width: 760px) { .founder .wrap { grid-template-columns: 1fr; } .photo { max-width: 160px; } .founder blockquote { font-size: 19px; } }

/* ---------- contact ---------- */
.contact { background: #fff; border-top: 1px solid var(--line); }
.contact .wrap { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 48px; }
.contact-form { display: grid; gap: 12px; min-width: 0; }
.form-row { display: grid; gap: 4px; }
.form-row label { font-size: 13.5px; font-weight: 600; color: var(--teal-deep); }
.form-row input, .form-row textarea { font: 15px var(--sans); padding: 10px 12px; border: 1px solid var(--line); border-radius: 6px; background: var(--paper); color: var(--ink); width: 100%; min-width: 0; }
.form-row textarea { min-height: 110px; resize: vertical; }
.formnote { font-size: 13px; color: var(--ink-soft); }
@media (max-width: 800px) { .contact .wrap { grid-template-columns: 1fr; } }

/* Honeypot container (issue #229). Off-screen rather than display:none —
   the comment on the element in landing.html explains why: some bots skip
   display:none fields, which would defeat the trap. #229 records the whole
   control and its false-positive cost — a real prospect silently rejected.

   Named for the TECHNIQUE, not the purpose. A class called "honeypot" would
   hand a bot reading the stylesheet the answer for free; the element itself
   carries no other distinguishing hook. */
.offscreen { position: absolute; left: -9999px; top: auto; width: 1px; height: 1px; overflow: hidden; }

/* ---------- final call to action + footer ---------- */
.final { background: var(--teal-deep); color: #fff; text-align: center; padding-block: 64px; }
.final h2 { color: #fff; }
.final p { color: #BFD2CF; margin-top: 10px; }
.final .cta { display: flex; gap: 12px; justify-content: center; flex-wrap: wrap; margin-top: 24px; }
.final .btn.ghost { border-color: #8FC3C9; color: #fff; }
footer.site { padding-block: 28px; font-size: 13.5px; color: var(--ink-soft); }
footer.site .wrap { display: flex; flex-wrap: wrap; gap: 10px 24px; justify-content: space-between; align-items: center; }

/* ---------- reveal on scroll ---------- */
/* Scoped to .js-reveal, which landing.js adds to <html> as its first
   statement. Content is therefore VISIBLE by default and only hidden once
   scripting is proven to work. Before this, .reveal was opacity:0
   unconditionally, so any failure to run landing.js at all — the CSP block
   that hid this page for days, a 404, a stale service-worker entry, JS
   disabled — blanked everything below the header. Now that same failure
   costs only the animation. Do not un-scope these two rules. */
.js-reveal .reveal { opacity: 0; transform: translateY(14px); transition: opacity .6s ease, transform .6s ease; }
.js-reveal .reveal.in { opacity: 1; transform: none; }

@media (max-width: 560px) { section { padding-block: 60px; } }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .js-reveal .reveal { transition: none; opacity: 1; transform: none; }
}
