/* ══════════════════════════════════════════════════════════════
   DooDurian — เครื่องมือ AI (ai-tools)

   Page CSS for the ai-tools.html hub and for the three tool pages it
   links to — scan.html, chat.html and weather.html.

   Lives in its own file (not a <style> block, no style="" attributes)
   because production serves `style-src 'self'`.
   Every colour comes from a token in styles.css — the mockup's dark
   forest palette is mapped onto the bright-green brand, never pasted.
   ══════════════════════════════════════════════════════════════ */

/* ─── Responsive copy ───────────────────────────────────────────
   A phone and a desktop are told different things in the design — "ลากรูปภาพ
   มาวาง" is not an action a thumb can take, and the phone's shorter line is
   not a truncation of the wide one, it is different wording. Only ever one of
   the pair is in the box; the other is display:none, so an assistive reader
   hears one sentence, not two. 620px is the same boundary FIELD MODE uses. */
.only-narrow { display: none; }
@media (max-width: 620px) {
  .only-wide { display: none; }
  .only-narrow { display: inline; }
}

/* ─── Phone: a tool page ends where the tool ends ────────────────
   The design's three tool screens have no footer — only the home and the
   about screens close with the © line. On a phone these pages are app
   screens, and a sitemap of links you reach by scrolling *past* the tool
   turns the bottom of the screen into somewhere you can fall out of the
   service. The tab bar is the navigation down there.

   Scoped by stylesheet, not by a selector: this file is loaded by scan,
   chat and weather and by nothing else, so the home and about pages keep
   their footer without needing to be named here. Above 620px the footer is
   the page's proper ending and stays on every page. */
@media (max-width: 620px) {
  .service-footer { display: none; }
}

/* ─── Shared type ───────────────────────────────────────────── */

/* Display serif, never below 22px per the type rules. */
.ait-title {
  font-family: var(--font-display);
  font-size: 30px; line-height: 1.22; font-weight: 700;
}

/* Selector carries .page-head because the shared `.page-head p` rule paints
   every paragraph in the header --text-muted and would otherwise win. */
.page-head .ait-eyebrow {
  font-size: 13px; line-height: 18px; font-weight: 600;
  letter-spacing: .14em; text-transform: uppercase;
  color: var(--gold-ink); margin-bottom: 10px;
}

/* Small gold-ink label that opens a block ("ผลที่เป็นไปได้สูงสุด"). */
.ait-kicker {
  font-size: 13px; line-height: 18px; font-weight: 600;
  letter-spacing: .08em; text-transform: uppercase;
  color: var(--gold-ink); margin: 0 0 10px;
}

.page-head .ait-lead {
  font-size: 17px; line-height: 1.7;
  color: var(--text-body); max-width: 64ch;
}

.ait-note { font-size: 14px; line-height: 1.6; color: var(--text-muted); margin-top: 14px; }
.ait-note--center { text-align: center; margin-top: 12px; }

.ait-back { margin-bottom: 16px; }
.ait-gap-top { margin-top: 22px; }

.ait-mono { font-family: var(--font-mono); font-size: 13px; }

/* ─── Layout helpers ────────────────────────────────────────── */
.ait-section { margin-bottom: 32px; }
.ait-section:last-child { margin-bottom: 0; }

.ait-stack { display: flex; flex-direction: column; gap: 16px; }

/* หน้าสแกนบนจอกว้าง: "วิธีถ่ายภาพ" ไปอยู่ข้างช่องอัปโหลด ไม่ใช่ใต้มัน — มันคือ
   สิ่งที่อ่าน "ระหว่าง" เลือกไฟล์ พอวางซ้อนกันมันไปโผล่ใต้ fold เฉพาะบนจอที่มี
   ที่เหลือเฟือ ตามดีไซน์ desktop (อัปโหลดซ้าย / วิธีถ่ายภาพขวา) */
@media (min-width: 901px) {
  .ait-stack--scan {
    display: grid;
    grid-template-columns: minmax(0, 1.35fr) minmax(0, 1fr);
    gap: 18px; align-items: start;
  }
  /* คอลัมน์ขวาแคบกว่าครึ่งจอ สองคอลัมน์ในนั้นทำให้ทุกข้อขึ้นบรรทัดที่สอง */
  .ait-stack--scan .photo-tips ol { grid-template-columns: 1fr; }
}

.ait-grid-2 { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 16px; }

.ait-actions { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 18px; }
.ait-actions--split > .btn { flex: 1 1 150px; }

/* ─── Numbered action steps ─────────────────────────────────── */
.ait-steps { display: flex; flex-direction: column; gap: 9px; counter-reset: ait-step; }
.ait-steps li {
  display: flex; gap: 12px; align-items: flex-start;
  background: var(--white); border: 1px solid var(--border);
  border-radius: var(--r-md); padding: 13px 15px;
  font-size: 15px; line-height: 1.55; color: var(--text);
}
.ait-steps li::before {
  counter-increment: ait-step; content: counter(ait-step);
  flex: none; width: 26px; height: 26px; border-radius: var(--r-full);
  background: var(--green); color: var(--white);
  font-size: 13px; font-weight: 700;
  display: flex; align-items: center; justify-content: center;
}

/* ─── Callout ───────────────────────────────────────────────── */
/* Shared .notice--warning carries the surface, border and warn heading.
   Only the reading sizes step up: this block is the one thing on the screen
   that must be read before anyone reaches for a sprayer. */
.ait-callout { margin-top: 0; padding: 16px; }
.ait-callout h3 { font-size: 17px; line-height: 26px; }
.ait-callout p { font-size: 15px; line-height: 1.65; color: var(--text-body); }

/* ─── Migration table (hub) ─────────────────────────────────── */
.ait-table-wrap {
  overflow-x: auto;
  border: 1px solid var(--border); border-radius: var(--r-xl);
  background: var(--white);
}
.ait-table { width: 100%; min-width: 760px; border-collapse: collapse; }
.ait-table caption { text-align: left; padding: 16px 20px 0; color: var(--text-muted); font-size: 14px; }
.ait-table th {
  text-align: left; padding: 13px 20px;
  background: var(--surface); border-bottom: 1px solid var(--border);
  font-size: 12px; line-height: 18px; font-weight: 600;
  letter-spacing: .06em; text-transform: uppercase; color: var(--text-muted);
}
.ait-table th:first-child { width: 240px; }
.ait-table th:nth-child(2) { width: 150px; }
.ait-table td {
  padding: 14px 20px; border-top: 1px solid var(--border);
  font-size: 15px; line-height: 1.55; color: var(--text-body);
  vertical-align: top;
}
.ait-table tbody tr:first-child td { border-top: 0; }
.ait-table__from { font-family: var(--font-mono); font-size: 13px; color: var(--text-muted); }
.ait-table__to { font-family: var(--font-mono); font-size: 13px; font-weight: 700; color: var(--green); }

/* ─── Scan · upload ─────────────────────────────────────────── */
.ait-drop {
  width: 100%; display: flex; flex-direction: column; align-items: center;
  gap: 14px; padding: 30px 20px; text-align: center;
  border: 2px dashed var(--border-strong); border-radius: var(--r-xl);
  background: var(--white); cursor: pointer;
  transition: border-color .18s, background-color .18s;
}
.ait-drop:hover { border-color: var(--green); background: var(--green-soft); }
/* The file input is visually hidden *inside* this label, so :focus-within is
   the only thing that can show a keyboard user where they are. */
.ait-drop:focus-within { outline: 3px solid var(--ring); outline-offset: 2px; }
.ait-drop__icon {
  width: 66px; height: 66px; border-radius: var(--r-full);
  background: var(--green); color: var(--white); font-size: 26px;
  display: flex; align-items: center; justify-content: center;
}
.ait-drop__title { font-size: 18px; line-height: 26px; font-weight: 600; color: var(--text); }
.ait-drop__sub { font-size: 14px; line-height: 22px; color: var(--text-muted); }

/* ─── Scan · analysing ──────────────────────────────────────────
   The wait stands where the answer will be: a line saying what the model is
   doing, then two bars the width of the first two lines of the result. */
.scan-busy { text-align: center; padding: 30px 0 10px; }
.scan-busy p { color: var(--text-muted); font-size: 14px; line-height: 22px; margin: 10px 0 0; }
.scan-busy__bars { display: flex; flex-direction: column; gap: 8px; margin-top: 16px; }
.scan-busy__bars .sk { height: 16px; border-radius: 8px; }
.scan-busy__bars .sk:last-child { width: 72%; }

/* The preview stays; the buttons that acted on it do not, because pressing
   "วิเคราะห์ภาพ" a second time while the first is in flight is not a thing
   the grower means to do. */
#app[data-state="loading"] .selected-grid__actions { display: none; }

/* ─── Scan · result ─────────────────────────────────────────── */
.ait-media { background: var(--surface); border-radius: var(--r-lg); overflow: hidden; margin-bottom: 18px; }
.ait-media img { width: 100%; height: 190px; object-fit: cover; }

/* Sits opposite a two-line section title, where a flex item shrinks by default
   and breaks "ไม่มั่นใจ" across lines. This one is a verdict — it holds a line. */
.ait-verdict { flex: none; white-space: nowrap; }

.ait-result__label { font-size: 26px; line-height: 34px; font-weight: 600; margin: 0 0 14px; }
.ait-result__disclaimer { font-size: 14px; line-height: 1.6; color: var(--text-muted); margin-top: 16px; }

/* Monospace because it gets read out over the phone and typed into a ticket. */
.result-list__req {
  font-family: var(--font-mono); font-size: 12px;
  color: var(--text-soft); margin-top: 10px; word-break: break-all;
}


/* ─── Scan · service states ─────────────────────────────────── */
.ait-state__head {
  display: flex; align-items: center; gap: 10px;
  padding: 13px 18px;
  background: var(--surface); border-bottom: 1px solid var(--border);
}
.ait-state__title { font-size: 15px; line-height: 24px; font-weight: 600; color: var(--forest); }
.ait-state__key { margin-left: auto; font-family: var(--font-mono); font-size: 12px; color: var(--text-muted); }
.ait-state__body { padding: 20px; }
.ait-empty--info .empty__icon { background: var(--info-soft); color: var(--info); }
.ait-empty--muted .empty__icon { background: var(--surface); color: var(--text-muted); }

/* ─── Chat ──────────────────────────────────────────────────── */
/* The shared .chat-head sizes its h1 for the sans face; the display serif
   needs its own step so it never drops under the 22px floor. */
.chat-head h1.ait-title { font-size: 26px; line-height: 34px; }
.chat-head .btn { flex: none; margin-left: auto; }
/* The serif is display-only and never below 22px, which the phone's 19px in
   the design would break — so the phone keeps the sans face at the floor. */
@media (max-width: 620px) {
  .chat-head h1.ait-title { font-family: var(--font); font-size: 22px; line-height: 30px; }
}

/* ─── Chat · the context strip, and where it sits ───────────────
   Markup order is the phone's: messages, then the strip, then the composer.
   Everything in this block is about honouring that on a phone and undoing it
   on a wide screen, where the design has the strip back above the
   conversation as a card of its own. */

/* The thread is a shade off white so the bot's own pale bubbles read as
   sitting on it rather than merging into it. */
.chat-messages { background: var(--surface-thread); }

/* Phone: a single scrolling row of pills resting on the composer. The label
   and the explanatory line are the wide screen's; here the pills say it. */
@media (max-width: 620px) {
  /* The conversation is the screen, not a card on a page. Full-bleed out of
     the container gutter, because the gutter plus the card's own padding was
     costing the composer 72px of a 375px row — enough that the placeholder
     wrapped to a second line inside a box one line tall and was cut off. */
  .chat-wrap { margin-inline: calc(var(--gutter) * -1); }
  .chat-head { padding-inline: var(--gutter); }
  .chat-panel { border-inline: 0; border-radius: 0; }
  .chat-messages { padding: 14px 14px 10px; }
  .chat-input-row { padding: 10px 12px 12px; gap: 6px; }
  /* Clears the raised AI button, which pokes 24px above the bar and would
     otherwise sit on top of the last line of this. */
  .chat-disclaimer { padding: 0 var(--gutter) 26px; }

  .chat-panel .context-bar {
    /* No order needed — the markup is already in the phone's order. */
    margin: 0; padding: 8px 12px 0;
    border: 0; border-top: 1px solid var(--border); border-radius: 0;
    background: var(--white);
  }
  .chat-panel .context-bar__header,
  .chat-panel .context-bar__hint { display: none; }

  /* nowrap + overflow, never wrap: a second row of chips would push the
     composer down by its own height every time one is attached. */
  .chat-panel .context-add,
  .chat-panel .context-chips {
    flex-wrap: nowrap; overflow-x: auto; scrollbar-width: none;
    gap: 6px; padding-bottom: 8px;
  }
  .chat-panel .context-add::-webkit-scrollbar,
  .chat-panel .context-chips::-webkit-scrollbar { display: none; }

  .chat-panel .context-add__btn,
  .chat-panel .context-chip {
    flex: none; white-space: nowrap;
    border-radius: var(--r-full); padding: 6px 11px; font-size: 12px;
  }
  /* "ยังไม่มีข้อมูล" is a second line inside a pill on a 375px row. The pill
     is a button to a page that says the same thing at the top of it. */
  .chat-panel .context-add__btn small { display: none; }
}

/* Wide: back above the conversation, as its own card. The panel gives up its
   chrome so the two blocks under it can carry it instead — messages and
   composer share an edge and read as the single card the design draws. */
@media (min-width: 621px) {
  .chat-panel {
    background: transparent; border: 0; border-radius: 0; overflow: visible;
  }
  .chat-panel .context-bar {
    order: -1;
    border: 1px solid var(--border); border-radius: var(--r-lg);
    margin-bottom: 12px;
  }
  .chat-messages {
    border: 1px solid var(--border); border-bottom: 0;
    border-radius: var(--r-xl) var(--r-xl) 0 0;
    min-height: 340px; max-height: 420px;
  }
  .chat-input-row {
    border: 1px solid var(--border);
    border-radius: 0 0 var(--r-xl) var(--r-xl);
  }
  /* Aligned with the bubbles rather than the panel: the suggestions are
     things the assistant is offering to say, and they line up under it. */
  .chat-messages .chat-suggestions { padding-left: 42px; }
}

/* The tips list keeps the shared two-column counter layout under an h3. */
.photo-tips h3 { margin-bottom: 12px; }

.chip.ait-chip--add {
  border-style: dashed; border-color: var(--border-strong);
  background: var(--white); color: var(--text-muted); font-weight: 500;
}
.chip.ait-chip--add:hover { border-color: var(--green); background: var(--green-soft); color: var(--forest); }

/* Shared .chat-msg__actions is a plain flex row, so the two icon buttons get
   squeezed under 48px by the labelled button beside them. Pin them square. */
.chat-msg__actions .btn { flex: 0 1 auto; min-width: 0; }
.chat-msg__actions .btn--icon { flex: none; }

.ait-typing {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 13px 16px; border-radius: var(--r-lg);
  background: var(--surface); border: 1px solid var(--border);
  font-size: 14px; line-height: 22px; color: var(--text-muted);
}
.ait-typing__dot { width: 8px; height: 8px; border-radius: 50%; background: var(--border); }
.ait-typing__dot:first-child { background: var(--green); }
.ait-typing__dot:nth-child(2) { background: var(--green-soft-border); }
.ait-typing__label { margin-left: 4px; }

/* Composer keeps the 48px floor that the shared textarea does not reach. */
.ait-composer { border-top: 1px solid var(--border); background: var(--white); }
.ait-composer .chat-suggestions { padding: 14px 16px 0; margin: 0; }
.ait-composer .chat-input-row { border-top: 0; }
.ait-composer textarea { min-height: var(--control-lg); padding: 13px 15px; font-size: 16px; }

/* ─── Weather · hero ────────────────────────────────────────────
   The gradient runs from the brand green into --green-deep so white type on
   it clears 4.6:1 all the way down; the warm wash in the top corner is the
   same --cream the rest of the service uses on green, at 28%. */
.wx-hero {
  border-radius: var(--r-xl); padding: 18px 20px 20px; margin-bottom: 14px;
  background:
    radial-gradient(90% 140% at 100% 0%, rgba(255, 243, 196, .28) 0%, transparent 55%),
    linear-gradient(135deg, var(--green) 0%, var(--green-deep) 100%);
}
.wx-hero__place {
  display: flex; align-items: center; gap: 8px;
  font-size: 15px; line-height: 24px; font-weight: 600;
  color: var(--gold-on-dark); margin: 0 0 4px;
}
.wx-hero__place i { font-size: 13px; }
.wx-hero__read { display: flex; align-items: flex-end; gap: 16px; flex-wrap: wrap; }
.wx-hero__temp { font-size: 52px; line-height: 1; font-weight: 700; color: var(--white); }
.wx-hero__of { padding-bottom: 5px; }
.wx-hero__cond { display: block; font-size: 16px; line-height: 24px; color: var(--white); }
.wx-hero__note { display: block; font-size: 13.5px; line-height: 20px; color: rgba(255, 255, 255, .72); }
.wx-hero__sub,
.wx-hero__grid-point {
  margin: 10px 0 0; font-size: 13px; line-height: 20px;
  color: rgba(255, 255, 255, .82);
}
.wx-hero__grid-point { margin-top: 2px; font-size: 12px; color: rgba(255, 255, 255, .66); font-variant-numeric: tabular-nums; }
.wx-hero__sub:empty, .wx-hero__grid-point:empty { display: none; }

@media (max-width: 620px) {
  .wx-hero__temp { font-size: 46px; }
  /* Two up, per the design. Six metrics in one column is six screens of
     scrolling past numbers to reach the forecast they belong to; the shared
     rule drops to one column because it is written for wider cards than
     these. */
  .weather-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }
  .weather-metric { padding: 13px 10px; }
  .weather-metric__value { font-size: 19px; line-height: 26px; }

  /* One row: the square that means "here", then the button that does the
     thing. Stacked, the primary action sat a whole control below the fold of
     the card it belongs to. */
  .weather-form__actions { flex-wrap: nowrap; gap: 8px; }
  #weatherLocationButton { flex: none; width: var(--control-md); padding: 0; }
  #weatherLoadButton { flex: 1; min-width: 0; }
}

/* ─── Weather · picking a location ──────────────────────────────
   The design's desktop setup screen: the picker on the left, and on the right
   the panel the forecast is about to occupy. On a phone the picker is the
   whole screen and .wx-idle is not rendered at all. */
.wx-idle { display: none; }

@media (min-width: 901px) {
  .wx-setup {
    display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1.15fr);
    gap: 18px; align-items: start;
  }
  /* The picker becomes one column of its own, because the second column of
     the page is now doing the job its right-hand half used to. Overrides the
     grid the shared sheet gives #pinCard. */
  #pinCard { display: block; }

  .wx-idle {
    display: flex; flex-direction: column; align-items: center; text-align: center;
    padding: 48px 28px;
    border: 1px dashed var(--border-strong); border-radius: var(--r-xl);
    background: linear-gradient(180deg, var(--surface) 0%, var(--white) 100%);
  }
  .wx-idle__icon {
    width: 58px; height: 58px; margin-bottom: 14px; border-radius: var(--r-full);
    background: var(--green-soft); color: var(--green-deep); font-size: 22px;
    display: inline-flex; align-items: center; justify-content: center;
  }
  .wx-idle__head { font-size: 18px; line-height: 26px; font-weight: 600; color: var(--text); margin: 0 0 7px; }
  .wx-idle__body { font-size: 15px; line-height: 1.65; color: var(--text-muted); margin: 0; max-width: 44ch; }
}

/* ─── Weather · advisory ────────────────────────────────────── */
.ait-advisory {
  background: var(--gold-soft); border: 1px solid var(--gold-soft-border);
  border-radius: var(--r-lg); padding: 18px;
}
.ait-advisory__head { font-size: 18px; line-height: 26px; font-weight: 600; color: var(--text); margin: 0 0 6px; }
.ait-advisory__body { font-size: 15px; line-height: 1.65; color: var(--text-body); margin: 0; }

/* ─── Weather · forecast rain bars ──────────────────────────── */
.ait-rain { display: flex; align-items: flex-end; gap: 5px; }
.ait-rain__col { flex: 1 1 0; display: flex; flex-direction: column; align-items: center; gap: 6px; min-width: 0; }
.ait-rain__slot { width: 100%; height: 78px; display: flex; align-items: flex-end; }
.ait-rain__bar { width: 100%; border-radius: 4px; background: var(--green-soft-border); }
.ait-rain__bar--mid { background: var(--green); }
.ait-rain__bar--high { background: var(--forest); }
.ait-rain__t { font-size: 11px; line-height: 16px; color: var(--text-muted); font-variant-numeric: tabular-nums; }

.ait-h8 { height: 8%; }
.ait-h12 { height: 12%; }
.ait-h16 { height: 16%; }
.ait-h22 { height: 22%; }
.ait-h30 { height: 30%; }
.ait-h44 { height: 44%; }
.ait-h58 { height: 58%; }
.ait-h72 { height: 72%; }
.ait-h86 { height: 86%; }

.ait-metrics { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; }

/* ─── Mobile ────────────────────────────────────────────────── */
@media (max-width: 720px) {
  .ait-title { font-size: 26px; }
  .ait-grid-2 { grid-template-columns: 1fr; }
  .ait-actions--split > .btn { flex: 1 1 100%; }
  .ait-rain { gap: 3px; }
  .ait-rain__slot { height: 64px; }
}

@media (max-width: 620px) {
  /* Side by side these two are 150px each with the label wrapped inside them.
     The design stacks them: one decision per row, each the full width of the
     thumb that presses it. */
  .drop-zone { padding: 30px 18px; }
  .drop-zone__actions { flex-direction: column; flex-wrap: nowrap; gap: 8px; }
  .drop-zone__actions .btn { width: 100%; }
}
