JavaScript is required. Please enable it to continue.
Your browser lacks required capabilities. Please upgrade it or switch to another to continue.
Loading…
/* HUD latéral — markup Twee (pas de génération JS). Attributs dynamiques : directives SugarCube @src / @style / @class (pas de <<= >> dans les quotes HTML). */ <<if not setup.gameData or not setup.gameData.meta or $money == null>> <div class="sidebar"><div class="sidebar__identity"><span class="sidebar__name"><<= (setup.gameData and setup.gameData.meta and setup.gameData.meta.playerName) or "Darius">></span></div></div> <<else>> <<set _meta to setup.gameData.meta>> <<set _logoUrl to (typeof setup.resolveAssetUrl === "function" ? setup.resolveAssetUrl("images/logo.webp") : "images/logo.webp")>> <<set _avatarUrl to (typeof setup.resolveAssetUrl === "function" ? setup.resolveAssetUrl("images/characters/darius.webp") : "images/characters/darius.webp")>> <<set _avatarStyle to "background-image:url('" + _avatarUrl + "');background-size:cover;background-position:center;color:transparent">> <<set _cashClass to ($money < 2000 ? "sidebar__cash-value sidebar__cash-value--low" : "sidebar__cash-value")>> <<set _lang to (typeof setup.getLang === "function" ? setup.getLang() : ($lang || "fr"))>> <div class="sidebar"> <div class="sidebar__brand"> <<if _meta.version>> <span class="sidebar__version">v<<= _meta.version >></span> <</if>> <img class="sidebar__logo" @src="_logoUrl" @alt="_meta.title || 'La Table Noire'" width="248" height="80" decoding="async"> </div> <div class="sidebar__identity"> <div class="sidebar__avatar" @style="_avatarStyle" title="Darius">DK</div> <div class="sidebar__who"> <span class="sidebar__name"><<= _meta.playerName >></span> <span class="sidebar__alias">"<<= _meta.playerAlias >>"</span> </div> </div> <div class="sidebar__calendar"> <span class="sidebar__day"><<= setup.getDayName() >></span> <span class="sidebar__week"><<= setup.t("common.week") >>. <<= $current_week >></span> <span class="sidebar__phase"><<= $time_phase === "night" ? setup.t("common.night") : setup.t("common.day") >></span> </div> <div class="sidebar__cash" data-sidebar-stat-wrap="money"> <span class="sidebar__cash-label"><<= setup.t("sidebar.cash") >></span> <span @class="_cashClass" data-sidebar-stat="money" data-stat-value="<<= $money >>"><<= setup.formatMoney($money) >></span> </div> <div class="sidebar__cash sidebar__cash--pd" data-sidebar-stat-wrap="pd"> <span class="sidebar__cash-label"><<= setup.t("sidebar.domination") >></span> <span class="sidebar__cash-value" data-sidebar-stat="pd" data-stat-value="<<= $domination_points != null ? $domination_points : 0 >>"><<= $domination_points != null ? $domination_points : 0 >> <<= setup.t("common.pd") >></span> </div> <div class="sidebar__cash sidebar__cash--rep" data-sidebar-stat-wrap="rep"> <span class="sidebar__cash-label"><<= setup.t("sidebar.reputation") >></span> <span class="sidebar__cash-value sidebar__cash-value--rep" data-sidebar-stat="rep" data-stat-value="<<= setup.getReputationPoints() >>"><<= setup.getReputationPoints() >> <<= setup.t("common.pts") >></span> </div> <<if $poker_active>> <div class="sidebar__section sidebar__section--live"> <div class="sidebar__section-title"><<= setup.t("sidebar.live") >></div> <div class="sidebar__statline"><span><<= setup.t("sidebar.hand") >></span><span><<= $poker_hand >> / <<= $poker_hands_total >></span></div> <div class="sidebar__statline"><span><<= setup.t("sidebar.pot") >></span><span class="gold-text"><<= setup.formatMoney($poker_pot) >></span></div> </div> <</if>> <div class="ltn-footer-nav"> <span class="navbtn btn-ghost btn-block"><<link `setup.t("sidebar.options")` "Options">><</link>></span> </div> </div> <</if>>
/* LA TABLE NOIRE v0.11 — initialisation data-driven (gameData.js) */ <<run setup.initGame()>> <<run setup.initStoryState()>>
/* Les macros jeu (page_header, display_char_status, skill_check, etc.) sont enregistrées en JavaScript via setup.registerGameMacros() dans StoryJavaScript.twee (Macro.add). Ne plus utiliser <<widget>> ici : l'enregistrement Twine est peu fiable dans ce build Tweego/SugarCube. */
<div class="ltn-shell"> <div class="title-screen ltn-hero"> <div class="ltn-hero-mark" aria-hidden="true">♠</div> <img src="images/title_logo.png" alt="" class="relative mx-auto mb-3 max-h-16 opacity-90" onerror="this.style.display='none'"> <h1 class="ltn-hero-title"><<= setup.t("meta.title").toUpperCase() >></h1> <p class="tagline ltn-hero-tagline"><<= setup.t("meta.tagline") >></p> <div class="ltn-hero-meta"> <span class="version-badge ltn-badge"><<= setup.t("start.version", { v: (setup.gameData.meta && setup.gameData.meta.version) || "0.9" }) >></span> </div> </div> <div class="ltn-quote"> <<= setup.t("start.quote") >> </div> <p class="ltn-prose mx-auto text-center"> <<t "start.blurb">> </p> <div class="title-actions ltn-actions"> <<link `setup.t("start.new_game")`>><<goto "Intro">><</link>> </div> </div>
<<silently>> <<run setup.ensureSkillsState()>> <<if !$lang>><<set $lang to setup.getLang()>><</if>> <<set _lang to setup.getLang()>> <<set _metaFr to setup.getLanguageMeta("fr")>> <<set _metaEn to setup.getLanguageMeta("en")>> /* Passage d'origine (avant Options) — figé au rendu */ <<set _optionsBack to previous()>> <<if !_optionsBack>><<set _optionsBack to "Hub">><</if>> <</silently>> <div class="ltn-shell"> <<print setup.renderPageHeader(setup.t("options.title"), setup.t("options.sub"), setup.t("common.menu"))>> <div class="ltn-panel my-4"> <p class="ltn-panel-kicker"><<= setup.t("options.language") >></p> <p class="ltn-panel-body !mt-1 !text-base text-ink-muted"><<= setup.t("options.language_hint") >></p> <label class="ltn-select-wrap !mt-3" for="ltn-lang-select"> <span class="sr-only"><<= setup.t("options.language") >></span> <<print setup.renderLanguageSelectHTML()>> </label> </div> <div class="ltn-actions ltn-actions--start"> <span class="navbtn btn-ghost"><<link `setup.t("common.back")` `_optionsBack`>><</link>></span> </div> </div> <<script>> /* Secours : bind après insertion du passage (onchange inline déjà présent) */ (function () { function bindLangSelect() { var sel = document.getElementById("ltn-lang-select"); if (!sel || sel._ltnLangBound) return; sel._ltnLangBound = true; try { var cur = typeof setup.getLang === "function" ? setup.getLang() : "fr"; sel.value = cur === "en" ? "en" : "fr"; } catch (e0) { /* ignore */ } sel.addEventListener("change", function () { var lang = sel.value === "en" ? "en" : "fr"; if (typeof setup.setLanguage === "function") { setup.setLanguage(lang); } }); } if (typeof jQuery !== "undefined") { jQuery(document).one(":passagedisplay", bindLangSelect); } setTimeout(bindLangSelect, 0); })(); <</script>>
<div class="ltn-shell"> <<print setup.renderPageHeader(setup.t("intro.title"), setup.t("intro.sub"), setup.t("intro.eyebrow"))>> <p class="ltn-prose"> <<t "intro.p1">> </p> <p class="ltn-prose"> <<t "intro.p2">> </p> <<set _introChar to setup.gameData.meta.introDebtChar>> <<set _introC to setup.characters[_introChar]>> <<set _introPreyVars to { name: _introC.displayName, debt: setup.formatMoney(setup.getCharVar(_introChar, "debt")) }>> <div class="ltn-panel ltn-panel--compact my-4"> <p class="ltn-panel-kicker"><<= setup.t("intro.first_prey") >></p> <p class="ltn-panel-body !mt-0 !text-base"> <<t "intro.first_prey_body" _introPreyVars>> </p> </div> <div class="ltn-quote"><<= setup.t("intro.quote") >></div> <div class="event-box ltn-objective"> <strong><<= setup.t("intro.objective_title") >></strong> <<t "intro.objective">> </div> <div class="ltn-actions ltn-actions--start"> <span class="navbtn btn-primary btn-block"><<link `setup.t("intro.enter_office")`>><<run setup.ensureSkillsState()>><<run setup.ensureEmpireState()>><<run setup.rollAudiencesIfNeeded()>><<set $time_phase to "day">><<set $narrative_context to "prologue">><<run setup.openNarrativeScene("prologue_marco_circle")>><</link>></span> </div> </div>
<<silently>> <<run setup.ensureSkillsState()>> <<run setup.ensureEmpireState()>> <<if !$lang>><<set $lang to setup.getLang()>><<run setup.applyLanguage($lang, { silent: true })>><</if>> <<if !$time_phase>><<set $time_phase to "day">><</if>> <<if $time_phase !== "night">><<run setup.rollAudiencesIfNeeded()>><</if>> <<set _go to setup.checkGameOver()>> <<if _go !== null>> <<goto _go>> <</if>> <<set _hubRedirect to setup.getHubRedirect()>> <<if _hubRedirect !== null>> <<goto _hubRedirect>> <</if>> <<set _isNight to ($time_phase === "night")>> <<set _audCount to setup.getAudienceCount()>> <<set _isAudDay to setup.isAudienceDay()>> <<set _debtorCount to setup.listDebtors().length>> <<set _loanCount to setup.getActiveLoans().length>> <<set _dayName to setup.getDayName()>> <<set _clubLine to setup.t("hub.club_day", { day: _dayName, week: $current_week })>> <<set _audLink to (!_isNight ? (_isAudDay ? setup.t("hub.audiences_n", { n: _audCount }) : setup.t("hub.audiences_closed")) : setup.t("hub.audiences"))>> <<set _circleLink to setup.t("hub.circle_n", { n: setup.listPokerCircle().length })>> <</silently>> <div class="ltn-shell"> <<if _isNight>> <<print setup.renderPageHeader(setup.t("hub.office_night"), _clubLine, setup.t("hub.phase_night"))>> <div class="mb-4 flex flex-wrap gap-2"> <span class="ltn-badge ltn-badge--night"><<= setup.t("common.night") >></span> <span class="ltn-badge"><<= $domination_points >> <<= setup.t("common.pd") >></span> <span class="ltn-badge ltn-badge--emerald"><<= setup.t("hub.nights_count", { n: $poker_nights_played }) >></span> <<if $forced_poker_tonight.length > 0>> <span class="ltn-badge ltn-badge--warn"><<= setup.t("hub.forced_count", { n: $forced_poker_tonight.length }) >></span> <</if>> </div> <<else>> <<print setup.renderPageHeader(setup.t("hub.office_day"), _clubLine, setup.t("hub.phase_day"))>> <div class="mb-4 flex flex-wrap gap-2"> <span class="ltn-badge ltn-badge--day"><<= setup.t("common.day") >></span> <span class="ltn-badge"><<= $domination_points >> <<= setup.t("common.pd") >></span> <span class="ltn-badge ltn-badge--emerald"><<= setup.t("hub.nights_count", { n: $poker_nights_played }) >></span> <<if _isAudDay>> <span class="ltn-badge ltn-badge--gold"><<= setup.t("hub.audience_count", { n: _audCount }) >></span> <<else>> <span class="ltn-badge"><<= setup.t("hub.no_audience_today") >></span> <</if>> </div> <</if>> <<if _isNight>> <p class="ltn-prose"><<t "hub.prose_night">></p> <<else>> <p class="ltn-prose"><<t "hub.prose_day">></p> <</if>> <<if $poker_skills_setup_locked || $poker_active>> <div class="alert alert--warn ltn-alert ltn-alert--warn"><<t "hub.setup_locked">></div> <</if>> <<if !_isNight && _isAudDay && _audCount > 0>> <<set _audVars to { n: _audCount }>> <div class="ltn-alert ltn-alert--warn"><<t "hub.audience_queue" _audVars>></div> <</if>> <<set _canParty to setup.canOrganizePokerNight()>> <div class="menu-hub ltn-menu"> <<if _isNight>> <<if _canParty.ok>> <span class="navbtn btn-primary btn-block"><<link `setup.t("hub.organize")` "Organize Game">><</link>></span> <<else>> <div class="menu-hub__locked" role="status" aria-live="polite"> <span class="menu-hub__locked-title"><<= setup.t("hub.party_closed") >></span> <span class="menu-hub__locked-msg"><<= _canParty.msg || setup.t("hub.party_closed_msg") >></span> </div> <</if>> <<else>> <span class="navbtn btn-primary btn-block"><<link `_audLink` "Audience Desk">><</link>></span> <span class="navbtn btn-primary btn-block"><<link `_circleLink` "Circle Desk">><</link>></span> <span class="navbtn btn-primary btn-block"><<link `setup.t("hub.staff")` "Staff Hire">><</link>></span> <span class="navbtn btn-secondary btn-block"><<link `setup.t("hub.network")` "Character Roster">><</link>></span> <span class="navbtn btn-secondary btn-block"><<link `setup.t("hub.ladder")` "Reputation Ladder">><</link>></span> <span class="navbtn btn-secondary btn-block"><<link `setup.t("hub.skills")` "CompetencesMenu">><</link>></span> <</if>> <<if _isNight>> <span class="navbtn btn-secondary btn-block"><<link `setup.t("hub.circle")` "Circle Desk">><</link>></span> <span class="navbtn btn-secondary btn-block"><<link `setup.t("hub.ladder")` "Reputation Ladder">><</link>></span> <span class="navbtn btn-secondary btn-block"><<link `setup.t("hub.skills")` "CompetencesMenu">><</link>></span> <span class="navbtn btn-secondary btn-block"><<link `setup.t("hub.network")` "Character Roster">><</link>></span> <</if>> <span class="navbtn btn-secondary btn-block"><<link `setup.t("hub.cards")` "Card Catalog">><</link>></span> <span class="navbtn btn-secondary btn-block"><<link `setup.t("hub.debts")` "Debt Ledger">><</link>></span> </div> <<if $last_ladder_unlocks && $last_ladder_unlocks.length > 0>> <div class="ltn-alert ltn-alert--success"> <<if $last_ladder_unlocks.length is 1>> <<t "hub.ladder_unlock_one">> <<else>> <<t "hub.ladder_unlock_many">> <</if>> </div> <<set $last_ladder_unlocks to []>> <</if>> <<set _phaseNextClass to "hub-phase-next hub-phase-next--" + (_isNight ? "day" : "night")>> <div @class="_phaseNextClass" role="region" aria-label="<<= setup.t('hub.next_phase') >>"> <div class="hub-phase-next__meta"> <span class="hub-phase-next__kicker"><<= setup.t("hub.next_phase") >></span> <<if !_isNight>> <span class="hub-phase-next__title"><<= setup.t("hub.night_can_fall") >></span> <span class="hub-phase-next__hint"><<= setup.t("hub.night_hint") >></span> <<else>> <span class="hub-phase-next__title"><<= setup.t("hub.end_night_title") >></span> <span class="hub-phase-next__hint"><<= setup.t("hub.end_night_hint") >></span> <</if>> </div> <<if !_isNight>> <span class="navbtn btn-primary hub-phase-next__btn"><<link `setup.t("hub.go_night")` "Go To Night">><</link>></span> <<else>> <span class="navbtn btn-primary hub-phase-next__btn"><<link `setup.t("hub.go_day")` "End Night To Day">><</link>></span> <</if>> </div> </div>
<<run setup.goToNight()>> <<goto "Hub">>
<<if $poker_active>> <div class="ltn-shell"> <<print setup.renderPageHeader(setup.t("hub.poker_active_title"), setup.t("hub.poker_active_sub"), setup.t("hub.attention"))>> <div class="ltn-alert ltn-alert--warn"><<= setup.t("hub.poker_active_warn") >></div> <div class="ltn-footer-nav"> <span class="navbtn btn-primary"><<link `setup.t("common.back")` "Hub">><</link>></span> </div> </div> <<else>> <<run setup.goToDay()>> <<goto "Hub">> <</if>>
/* Compat : redirige vers la transition nuit -> jour si besoin */ <<if $time_phase is "night" && !$poker_active>> <<goto "End Night To Day">> <<else>> <<run setup.goToDay()>> <<goto "Hub">> <</if>>
<<run setup.ensureEmpireState()>> <<run setup.refreshForcedPokerFromLoans()>> <<set _loans to setup.getActiveLoans()>> <<set _recInterval to setup.getRecoveryIntervalDays()>> <<set _dailyRatePct to Math.round((setup.getDailyDebtInterestRate() || 0.05) * 100)>> <<set _dueTomorrow to setup.formatMoney(setup.getTotalDueTomorrow())>> <div class="ltn-shell"> <<print setup.renderPageHeader(setup.t("debt.ledger"), setup.t("debt.ledger_sub"), setup.t("debt.accounts"))>> <div class="mb-3 flex flex-wrap gap-2"> <<if _loans.length > 0>> <span class="ltn-badge ltn-badge--emerald"><<= _loans.length >> <<= setup.tf("prêt(s) actifs", "active loan(s)") >></span> <</if>> <span class="ltn-badge ltn-badge--warn"><<= setup.t("debt.interest_day", { n: _dailyRatePct }) >></span> <span class="ltn-badge ltn-badge--warn"><<= setup.t("debt.due_tomorrow", { amount: _dueTomorrow }) >></span> <span class="ltn-badge"><<= setup.t("debt.recovery_every", { n: _recInterval }) >></span> </div> <<if $last_debt_interest_gained && $last_debt_interest_gained > 0>> <<set _intVars to { amount: setup.formatMoney($last_debt_interest_gained) }>> <div class="alert alert--info mb-3"><<t "debt.interest_night" _intVars>></div> <</if>> <<set _recInfoVars to { n: _recInterval }>> <div class="alert alert--info mb-3"><<t "debt.recovery_interval_info" _recInfoVars>></div> <div class="data-table-wrap ltn-table-wrap"> <table class="data-table"> <thead> <tr> <th><<= setup.t("debt.player") >></th> <th><<= setup.t("debt.debt") >></th> <th><<= setup.t("debt.stress") >></th> <th><<= setup.t("debt.control") >></th> <th></th> </tr> </thead> <tbody> <<for _cid range setup.characterIds>> <<if setup.isCollectibleDebtor(_cid)>> <<capture _cid>> <<set _c to setup.characters[_cid]>> <<set _debt to Number(setup.getCharVar(_cid, "debt")) || 0>> <<set _stress to Number(setup.getCharVar(_cid, "stress")) || 0>> <<set _recDue to setup.isRecoveryOfferDue(_cid)>> <<set _recWait to setup.getRecoveryDaysUntilOffer(_cid)>> <<if _debt >= 3000>> <<set _debtClass to "debt-high">> <<else>> <<set _debtClass to "">> <</if>> <tr> <td><<print _c.displayName>></td> <td class="<<print _debtClass>>"><<print setup.formatMoney(_debt)>></td> <td><<print _stress>> %</td> <td><<print setup.renderControlBadge(_cid)>></td> <td> <<if _recDue>> <span class="navbtn btn-secondary"><<link `setup.t("debt.recover")`>><<set $recovery_char to _cid>><<goto "Recovery Menu">><</link>></span> <<else>> <span class="navbtn btn-ghost is-disabled"><<= setup.t("debt.in_days", { n: _recWait }) >></span> <</if>> </td> </tr> <</capture>> <</if>> <</for>> </tbody> </table> </div> <div class="ltn-footer-nav"> <span class="navbtn btn-secondary"><<link `setup.t("debt.audiences")` "Audience Desk">><</link>></span> <span class="navbtn btn-ghost"><<link `setup.t("common.back_hub")` "Hub">><</link>></span> </div> </div>
<div class="ltn-shell"> <<print setup.renderPageHeader(setup.t("network.title"), setup.t("network.sub"), setup.t("hub.network"))>> <div class="space-y-4"> <<for _cid range setup.characterIds>> <<if setup.hasMetCharacter(_cid)>> <<print setup.renderCharStatus(_cid)>> <</if>> <</for>> </div> <div class="ltn-footer-nav"> <span class="navbtn btn-secondary"><<link `setup.t("common.back_hub")` "Hub">><</link>></span> </div> </div>
<<run setup.ensureSkillsState()>> <div class="ltn-shell"> <<print setup.renderPageHeader(setup.t("skills.title"), setup.tf("Points de Domination · Setup de 4 compétences actives", "Domination Points · Active 4-skill setup"), setup.tf("Compétences", "Skills"))>> <p class="ltn-prose mb-4"><<= setup.tf( 'Équipe jusqu\'à <strong class="text-gold-light">4 compétences actives</strong> pour la table. Les passives s\'appliquent dès le déblocage. Pendant une soirée, le setup est <strong class="text-amber">verrouillé</strong>.', 'Equip up to <strong class="text-gold-light">4 active skills</strong> for the table. Passives apply as soon as unlocked. During a night, the setup is <strong class="text-amber">locked</strong>.' ) >></p> <div id="competences-root" class="competences-root"> <p class="card-gallery__loading ltn-panel ltn-panel--compact text-ink-muted"><<= setup.t("common.loading") >></p> </div> <div class="ltn-footer-nav"> <span class="navbtn btn-primary"><<link `setup.t("skills.validate")` "Hub">><</link>></span> <span class="navbtn btn-secondary"><<link `setup.t("common.back_hub")` "Hub">><</link>></span> </div> </div> <<script>> (function () { var done = false; function boot() { if (done) return; if (!document.getElementById("competences-root")) return; done = true; if (typeof setup.mountCompetencesMenu === "function") { setup.mountCompetencesMenu(); } else if (typeof setup.renderCompetencesMenu === "function") { var root = document.getElementById("competences-root"); if (root) root.innerHTML = setup.renderCompetencesMenu(); } } setTimeout(boot, 0); $(document).one(":passagedisplay", boot); })(); <</script>>
<div class="ltn-shell"> <<print setup.renderPageHeader(setup.t("cards.catalog"), setup.t("cards.catalog_sub"), setup.t("cards.gallery"))>> <div class="card-gallery-toolbar mb-4 flex flex-wrap gap-2" id="ltn-card-gallery-toolbar" hidden> <button type="button" class="card-gallery-filter is-active" data-suit="all"><<= setup.t("cards.all") >></button> <button type="button" class="card-gallery-filter" data-suit="spades"><<= setup.t("cards.spades") >></button> <button type="button" class="card-gallery-filter" data-suit="hearts"><<= setup.t("cards.hearts") >></button> <button type="button" class="card-gallery-filter" data-suit="diamonds"><<= setup.t("cards.diamonds") >></button> <button type="button" class="card-gallery-filter" data-suit="clubs"><<= setup.t("cards.clubs") >></button> </div> <div id="ltn-card-gallery" class="card-gallery ltn-panel !p-4" aria-live="polite"> <p class="card-gallery__loading text-ink-muted"><<= setup.t("cards.loading") >></p> </div> <div class="ltn-footer-nav"> <span class="navbtn btn-secondary"><<link `setup.t("common.back_hub")` "Hub">><</link>></span> </div> </div> <<script>> (function () { var done = false; function boot() { if (done) return; if (!document.getElementById("ltn-card-gallery")) return; done = true; if (typeof setup.mountCardGallery === "function") { setup.mountCardGallery("ltn-card-gallery"); } } setTimeout(boot, 40); $(document).one(":passagedisplay", function () { setTimeout(boot, 20); }); })(); <</script>>
<<silently>> <<set _gate to setup.canOrganizePokerNight()>> <<if !_gate.ok>> <<goto "Hub">> <</if>> <<run setup.ensurePokerGuests()>> <<set _poker to setup.gameData.poker>> <<set _orgSub to setup.t("organize.sub", { min: _poker.minGuests, max: _poker.maxGuests })>> <</silently>> <div class="ltn-shell"> <<print setup.renderPageHeader(setup.t("organize.title"), _orgSub, setup.t("organize.eyebrow"))>> <div class="invite-intro ltn-panel flex items-start gap-4"> <div class="invite-intro__icon flex h-12 w-12 shrink-0 items-center justify-center rounded-xl border border-gold/40 bg-gold/15 text-2xl text-gold-light" aria-hidden="true">♠</div> <div> <p class="invite-intro__title ltn-panel-title !text-lg"><<= setup.t("organize.ready_title") >></p> <p class="invite-intro__text ltn-panel-body"><<= setup.t("organize.ready_text") >></p> </div> </div> <div id="organize-root" class="organize-root mt-4"> <p class="invite-loading ltn-panel ltn-panel--compact text-ink-muted"><<= setup.t("organize.loading") >></p> </div> <div class="ltn-footer-nav"> <span class="navbtn btn-ghost"><<link `setup.t("common.back_hub")` "Hub">><</link>></span> </div> </div> <<script>> (function () { var done = false; function boot() { if (done) return; if (!document.getElementById("organize-root")) return; done = true; if (typeof setup.mountOrganizeUI === "function") { setup.mountOrganizeUI("organize-root"); } } setTimeout(boot, 40); $(document).one(":passagedisplay", function () { setTimeout(boot, 20); }); })(); <</script>>
<<silently>> /* Une soirée max / nuit : bloquer une 2e orga ; si session déjà live, renvoyer à la table */ <<if $poker_active>> <<goto "Poker Live Night">> <<elseif $poker_night_held>> <<goto "Hub">> <<else>> <<run setup.initPokerSession()>> <<set $poker_nights_played to $poker_nights_played + 1>> <</if>> <</silently>> <<set _pokerIntroSub to setup.t("poker.intro_sub", { n: $poker_nights_played, guests: $poker_guests.length })>> <<print setup.renderPageHeader(setup.t("poker.intro_title"), _pokerIntroSub, setup.t("poker.intro_eyebrow"))>> <img src="images/backgrounds/poker_room.webp" alt="" class="scene-image" onerror="this.style.display='none'"> <p><<= setup.t("poker.intro_prose") >></p> <<= setup.t("poker.intro_tonight") >> <<for _g range $poker_guests>> <<print setup.renderCharStatus(_g)>> <</for>> <<set _handsVars to { n: $poker_hands_total }>> <div class="alert alert--info"><<t "poker.intro_hands" _handsVars>></div> <span class="navbtn btn-primary btn-block"><<link `setup.t("poker.sit")` "Poker Live Night">><</link>></span>
<div id="ltn-poker-status"><<= setup.t("poker.preparing") >></div> <div id="ltn-poker-app" class="ltn-poker app ltn-poker--split"> <!-- Colonne gauche : infos + contrôles --> <aside class="poker-side" id="poker-side"> <header class="topbar topbar--side"> <div class="brand"> <span class="brand__mark">♠</span> <div> <h1 class="brand__title"><<= setup.t("meta.title") >></h1> <p class="brand__sub"><<= setup.t("poker.brand_sub") >></p> </div> </div> <div class="topbar__stats topbar__stats--col"> <div class="stat-pill"> <span class="stat-pill__label"><<= setup.t("poker.hand_label") >></span> <span class="stat-pill__value" id="hand-number">1</span> </div> <div class="stat-pill stat-pill--gold"> <span class="stat-pill__label"><<= setup.t("poker.chips_label") >></span> <span class="stat-pill__value" id="hero-stack">—</span> </div> <div class="stat-pill"> <span class="stat-pill__label"><<= setup.t("poker.phase_label") >></span> <span class="stat-pill__value" id="phase-label"><<= setup.t("poker.phase_ready") >></span> </div> </div> </header> <footer class="actionbar actionbar--side" id="actionbar"> <!-- Statut affiché au centre du board (#board-status) --> <div class="actionbar__message" id="status-message" hidden><<= setup.t("poker.cards_coming") >></div> <div class="actionbar__controls actionbar__controls--col" id="controls"> <button type="button" class="btn btn--ghost" id="btn-fold" disabled><<= setup.t("poker.fold") >></button> <button type="button" class="btn btn--secondary" id="btn-check" disabled><<= setup.t("poker.check") >></button> <button type="button" class="btn btn--success" id="btn-call" disabled><<= setup.t("poker.call") >></button> <div class="raise-group raise-group--col"> <input type="range" id="raise-slider" min="20" max="200" step="10" value="40" disabled /> <button type="button" class="btn btn--primary" id="btn-raise" disabled> <<= setup.t("poker.raise") >> <span id="raise-amount">40</span> </button> </div> <button type="button" class="btn btn--gold" id="btn-deal"><<= setup.t("poker.new_hand") >></button> </div> <div class="actionbar__tools actionbar__tools--col"> <div class="shark-skills" id="shark-skills"> <div class="shark-skills__title"><<= setup.t("poker.actions_title") >></div> <div class="shark-skills__list" id="shark-skills-list"></div> <p class="shark-skills__msg" id="shark-skills-msg"></p> </div> </div> <div class="poker-escape"><span class="navbtn btn-ghost"><<link `setup.t("poker.leave")` "Poker Night End">><</link>></span></div> </footer> </aside> <!-- Colonne centre : board --> <main class="table-wrap" id="table-wrap"> <div class="felt" id="felt" aria-label="Poker table"> <div class="felt__ring"></div> <div class="felt__logo"><<= setup.t("meta.title").toUpperCase() >></div> <section class="seats seats--opponents" id="opponents"></section> <section class="board-zone"> <div class="pot-display" id="pot-display"> <span class="pot-display__chip" aria-hidden="true"></span> <div> <span class="pot-display__label"><<= setup.t("poker.pot_label") >></span> <span class="pot-display__value" id="pot-value">0</span> </div> </div> <div class="board-feed" id="board-feed" aria-live="polite"> <p class="board-feed__status" id="board-status"><<= setup.t("poker.cards_coming") >></p> <p class="board-feed__event" id="board-event" hidden></p> </div> <div class="community" id="community" aria-label="Cartes communes"></div> <p class="hand-banner" id="hand-banner" hidden></p> </section> <section class="seat seat--hero" id="hero-seat"> <div class="seat__info"> <div class="seat__avatar seat__avatar--hero">D</div> <div class="seat__meta"> <span class="seat__name">Darius « The Shark »</span> <span class="seat__stack" id="hero-stack-seat">—</span> </div> <span class="seat__bet" id="hero-bet" hidden></span> <span class="seat__status" id="hero-status" hidden></span> </div> <div class="seat__cards" id="hero-cards"></div> <p class="seat__hand-name" id="hero-hand-name"></p> </section> </div> </main> <!-- Colonne droite : historique des actions --> <aside class="poker-log" id="poker-log" aria-label="<<= setup.t('poker.log_title') >>"> <section class="action-log" id="action-log"> <div class="action-log__head"> <span class="action-log__title"><<= setup.t("poker.log_title") >></span> <span class="action-log__count" id="action-log-count">0</span> </div> <ul class="action-log__list" id="action-log-list"></ul> </section> </aside> <div class="toast" id="toast" hidden role="status"></div> <div class="modal" id="modal" hidden> <div class="modal__card"> <h2 class="modal__title" id="modal-title"><<= setup.t("poker.resolution") >></h2> <p class="modal__body" id="modal-body"></p> <button type="button" class="btn btn--primary" id="modal-ok"><<= setup.t("common.continue") >></button> </div> </div> </div> <<script>> (function () { document.body.classList.add("ltn-poker-night"); /* Panel joueur (UIBar) reste ouvert — ne pas stow */ var booted = false; var boot = function () { if (booted) return; if (!document.getElementById("ltn-poker-app")) return; booted = true; var st = document.getElementById("ltn-poker-status"); if (typeof setup.startLivePokerNight === "function") { setup.startLivePokerNight(); } setTimeout(function () { if (st && st.textContent.indexOf("Impossible") === -1) { st.textContent = ""; } }, 600); }; setTimeout(boot, 80); $(document).one(":passagedisplay", function () { setTimeout(boot, 30); }); })(); <</script>>
/* Compat : redirige vers la table live */ <<goto "Poker Live Night">>
<<set $poker_hand_action to "call">> <<goto "Poker Hand Resolve">>
<<set $poker_hand_action to "raise">> <<goto "Poker Hand Resolve">>
/* Triche retirée — renvoie à la table live */ <<goto "Poker Live Night">>
<<run setup.resolveHandLogic()>> <<print setup.renderPageHeader(setup.t("poker.resolution"), "Main " + ($poker_hand - 1))>> <<if $poker_last_winner is "darius">> <div class="result-card result-card--win"> <strong>Tu écrases la table.</strong> Le pot est à toi. Les perdants baissent les yeux. </div> <<set _loser to $poker_active_players[0]>> <<for _g range $poker_active_players>> <<if setup.getCharVar(_g, "stress") >= setup.getCharVar(_loser, "stress")>><<set _loser to _g>><</if>> <</for>> <div class="narrative"><<print setup.characters[_loser].displayName>> tremble sous ta victoire. +Contrôle sur chaque perdant.</div> <<else>> <<if setup.characters[$poker_last_winner]>> <<set _wName to setup.characters[$poker_last_winner].displayName>> <<else>> <<set _wName to $poker_last_winner>> <</if>> <div class="result-card result-card--lose"> <strong><<print _wName>> remporte la main.</strong> </div> <div class="narrative">Un regard de défi. Pas ce soir.</div> <</if>> <ul class="score-list"> <<for _pid, _score range $poker_last_scores>> <<if _pid is $poker_last_winner>> <<set _rowClass to "winner">> <<else>> <<set _rowClass to "">> <</if>> <<if _pid is "darius">> <<set _pName to "Darius (toi)">> <<elseif setup.characters[_pid]>> <<set _pName to setup.characters[_pid].displayName>> <<else>> <<set _pName to _pid>> <</if>> <li class="<<print _rowClass>>"> <span><<print _pName>></span> <span><<print _score>></span> </li> <</for>> </ul> <<if $poker_hand <= $poker_hands_total>> <span class="navbtn btn-primary btn-block"><<link `setup.t("poker.back_table")` "Poker Live Night">><</link>></span> <<else>> <span class="navbtn btn-primary btn-block"><<link `setup.t("poker.end_night_full")` "Poker Night End">><<set $poker_night_finished_ok to true>><</link>></span> <</if>>
/* Pénalité départ anticipé AVANT de clear livePoker / poker_active */ <<run setup.applyEarlyLeaveReputationPenalty()>> /* Scanner les cartes set encore sur la table (avant destruction live) */ <<run setup.harvestSetCardsFromLivePoker()>> <<set $poker_active to false>> /* Snapshot live (main / deck) — plus besoin après la soirée */ <<run setup.clearPokerLiveSnapshot()>> <<run setup.unlockSkillSetup()>> <<run $("body").removeClass("ltn-poker-night")>> <<run setup.livePoker = null>> <<silently>> <<run (function () { var v = State.variables; if (!Array.isArray(v.poker_night_table) || !v.poker_night_table.length) { if (Array.isArray(v.poker_active_players) && v.poker_active_players.length) { v.poker_night_table = v.poker_active_players.slice(); } else if (Array.isArray(v.poker_guests) && v.poker_guests.length) { v.poker_night_table = v.poker_guests.slice(); } else { v.poker_night_table = []; } } (v.poker_night_table || []).forEach(function (gid) { setup.setCharVar( gid, "sessions_played", (setup.getCharVar(gid, "sessions_played") || 0) + 1 ); }); /* * Cartes spéciales : effets déjà appliqués à la révélation. * Finalise le récap + filet board/héros avant le decay de stress. */ if (typeof setup.applySetCardNightBonuses === "function") { setup.applySetCardNightBonuses(); } /* Après la table : légère retombée (la grosse respiration est au passage jour) */ if (typeof setup.decayStressBetweenSessions === "function") { setup.decayStressBetweenSessions({ strength: 0.2 }); } })() >> <<set _pdGain to setup.awardNightDomination()>> <<run setup.buildDebtQueue()>> <<set $poker_guests to []>> <<set $time_phase to "night">> <</silently>> <<print setup.renderPageHeader(setup.t("poker.end_night"), setup.tf("Nuit ", "Night ") + $poker_nights_played, setup.tf("Après la table", "After the table"))>> <div class="narrative"><<= setup.tf("Les verres sont vides. Les cendres s'accumulent. Avant les dettes — le bilan de la table.", "Glasses empty. Ash piles up. Before the debts — the table recap.") >></div> <<if $poker_left_early>> <div class="alert alert--danger"><strong><<= setup.tf("Départ anticipé.", "Left early.") >></strong> <<= setup.tf("Tu as quitté la table avant la fin de la soirée — la salle murmure.", "You left the table before the night ended — the room whispers.") >> <strong><<= $poker_early_leave_penalty >> <<= setup.t("common.pts") >> <<= setup.t("common.reputation").toLowerCase() >></strong>.</div> <</if>> <div class="alert alert--success"><strong>+<<= $last_night_pd >> <<= setup.tf("Points de Domination", "Domination Points") >></strong> (<<= setup.tf("total", "total") >> : <<= $domination_points >> <<= setup.t("common.pd") >>). <<= setup.tf("L'Arsenal est de nouveau modifiable.", "The Arsenal can be changed again.") >></div> <<if $last_set_card_bonus && $last_set_card_bonus.cards && $last_set_card_bonus.cards.length > 0>> <div class="alert alert--info set-card-bonus-recap"> <strong><<= setup.tf("Cartes spéciales — effets à la révélation", "Special cards — reveal effects") >></strong> (<<= setup.tf("cumul de la soirée", "night total") >>). <<for _sci to 0; _sci lt $last_set_card_bonus.cards.length; _sci++>> <<set _sc to $last_set_card_bonus.cards[_sci]>> <span class="set-card-bonus-recap__item"><span class="set-card-bonus-recap__code"><<= _sc.code >></span> <<= _sc.label >><<if _sc.kind === "stress">> (<<= setup.tf("adversaires", "opponents") >>)<</if>></span><<if _sci lt $last_set_card_bonus.cards.length - 1>> · <</if>> <</for>> <<if $last_set_card_bonus.pd > 0>> — <strong>+<<= $last_set_card_bonus.pd >> <<= setup.t("common.pd") >></strong> <</if>> <<if $last_set_card_bonus.cash > 0>> — <strong>+<<= setup.formatMoney($last_set_card_bonus.cash) >></strong> <</if>> <<if $last_set_card_bonus.reputation > 0>> — <strong>+<<= $last_set_card_bonus.reputation >> <<= setup.tf("réput.", "rep.") >></strong> <</if>> <<if $last_set_card_bonus.stress > 0>> — <strong>+<<= $last_set_card_bonus.stress >> <<= setup.t("debt.stress").toLowerCase() >></strong> / <<= setup.tf("adversaire", "opponent") >> <</if>> </div> <</if>> <<print setup.renderPokerNightRecapHTML()>> <<if $debt_queue.length > 0>> <div class="alert alert--info"><<= $debt_queue.length >> <<= setup.tf("joueur(s) te doivent de l'argent. Passe au règlement quand tu as lu le bilan.", "player(s) owe you money. Go to settlement when you've read the recap.") >></div> <span class="navbtn btn-primary btn-block"><<link `setup.t("poker.pass_payments")` "Debt Settlement Start">><</link>></span> <<else>> <div class="alert alert--success"><<= setup.tf("Personne ne doit rien de significatif ce soir.", "Nobody owes anything significant tonight.") >></div> <span class="navbtn btn-secondary btn-block"><<link `setup.t("poker.back_hub_night")` "Hub">><</link>></span> <span class="navbtn btn-secondary btn-block"><<link `setup.t("poker.end_night_day")` "End Night To Day">><</link>></span> <</if>>
<<if $debt_index < $debt_queue.length>> <<set $debt_current_char to $debt_queue[$debt_index].id>> <<set _amount to $debt_queue[$debt_index].amount>> <<goto "Debt Settlement Character">> <<else>> <div class="ltn-shell"> <<print setup.renderPageHeader(setup.t("debt.settlement"), setup.tf("La table est débarrassée. Il ne reste que les comptes.", "The table is cleared. Only the books remain."), setup.tf("Après la table", "After the table"))>> <div class="ltn-quote">Dans ce monde, une dette n'est jamais qu'un début de conversation.</div> <div class="ltn-frame ltn-frame--success p-5"> <p class="m-0 text-ink-soft">Tous les comptes de cette soirée ont été traités.</p> </div> <div class="ltn-footer-nav"> <span class="navbtn btn-primary"><<link `setup.t("common.back_hub")` "Hub">><</link>></span> </div> </div> <</if>>
<<set _char to $debt_current_char>> <<set _c to setup.characters[_char]>> <<set _amount to setup.getSessionDebt(_char)>> <<set _canCash to setup.canUsePaymentAction("cash", _char)>> <<set _canPressure to setup.canUsePaymentAction("pressure", _char)>> <<set _canArrangement to setup.canUsePaymentAction("arrangement", _char)>> <<set _canLetRide to setup.canUsePaymentAction("letRide", _char)>> <div class="ltn-shell"> <<print setup.renderPageHeader(setup.t("debt.settlement_char", { name: _c.displayName }), setup.tf("Session : ", "Session: ") + setup.formatMoney(_amount) + " · Total : " + setup.formatMoney(setup.getCharVar(_char, "debt")), setup.t("debt.settlement"))>> <<print setup.renderCharStatus(_char)>> <div class="ltn-alert ltn-alert--info"><<= setup.tf("Contrôle : ", "Control: ") >><<print setup.renderControlBadge(_char)>> <<= setup.tf("— Les arrangements se font en recouvrement, pas ici", "— Arrangements happen during recovery, not here") >></div> <<if setup.getCharVar(_char, "stress") >= 70>> <div class="ltn-alert ltn-alert--danger"><<= setup.t("debt.stress_high") >></div> <<elseif setup.getCharVar(_char, "stress") >= 40>> <div class="ltn-alert ltn-alert--warn"><<= setup.t("debt.stress_mid") >></div> <<else>> <div class="ltn-alert ltn-alert--info"><<= setup.t("debt.stress_low") >></div> <</if>> <<set _lCash to setup.t("debt.demand_cash")>> <<set _lPress to setup.t("debt.raise_pressure")>> <<set _lArr to setup.t("debt.special_arr")>> <<set _lRide to setup.t("debt.let_ride")>> <div class="ltn-choices debt-choices"> <<if _canCash.ok>> <div class="ltn-choice ltn-choice--cash debt-choice debt-choice--cash"> <span class="navbtn btn-block"><<link _lCash "Debt Choice Cash">><</link>></span> </div> <<else>> <div class="recovery-choice recovery-choice--locked"> <span class="recovery-choice__label"><<= _lCash >></span> <span class="recovery-choice__cost"><<print _canCash.msg>></span> </div> <</if>> <<if _canPressure.ok>> <div class="ltn-choice ltn-choice--pressure debt-choice debt-choice--pressure"> <span class="navbtn btn-block"><<link _lPress "Debt Choice Pressure">><</link>></span> </div> <<else>> <div class="recovery-choice recovery-choice--locked"> <span class="recovery-choice__label"><<= _lPress >></span> <span class="recovery-choice__cost"><<print _canPressure.msg>></span> </div> <</if>> <<if _canArrangement.ok>> <div class="ltn-choice ltn-choice--arrangement debt-choice debt-choice--arrangement"> <span class="navbtn btn-block"><<link _lArr "Debt Choice Arrangement">><</link>></span> </div> <<else>> <div class="recovery-choice recovery-choice--locked"> <span class="recovery-choice__label"><<= _lArr >></span> <span class="recovery-choice__cost"><<print _canArrangement.msg>></span> </div> <</if>> <<if _canLetRide.ok>> <div class="ltn-choice ltn-choice--ride debt-choice debt-choice--ride"> <span class="navbtn btn-block"><<link _lRide "Debt Choice Let Ride">><</link>></span> </div> <<else>> <div class="recovery-choice recovery-choice--locked"> <span class="recovery-choice__label"><<= _lRide >></span> <span class="recovery-choice__cost"><<print _canLetRide.msg>></span> </div> <</if>> </div> </div>
<<run setup.doProcessDebtCash($debt_current_char)>> <<set _c to setup.characters[$debt_current_char]>> <div class="ltn-shell"> <<print setup.renderPageHeader(setup.t("debt.cash"), _c.displayName, setup.t("debt.debt"))>> <<if _debt_paid > 0>> <div class="ltn-frame ltn-frame--success p-5"> <p class="m-0 ltn-prose"><<print _c.displayName>> sort un énorme soupir et compte les billets. <strong class="text-gold-light"><<print setup.formatMoney(_debt_paid)>></strong> changent de mains.</p> <<if _debt_remaining > 0>> <p class="mt-2 mb-0 text-sm text-ink-soft">Il/Elle ne peut pas tout payer. Reste : <<print setup.formatMoney(_debt_remaining)>>.</p> <</if>> </div> <<else>> <div class="ltn-frame ltn-frame--danger p-5"> <p class="m-0">« Je n'ai rien, Darius. Rien. » Les mains tremblent.</p> <p class="mt-2 mb-0 text-sm text-[#ffb0bc]">Aucun paiement possible.</p> </div> <</if>> <<set $debt_index to $debt_index + 1>> <div class="ltn-footer-nav"> <span class="navbtn btn-primary"><<link `setup.t("common.next")`>><<goto "Debt Settlement Start">><</link>></span> </div> </div>
<<run setup.doProcessDebtPressure($debt_current_char)>> <<set _c to setup.characters[$debt_current_char]>> <div class="ltn-shell"> <<print setup.renderPageHeader(setup.t("debt.pressure"), _c.displayName, setup.tf("Intimidation", "Intimidation"))>> <<intimidation_check>> <<if $last_check_success>> <div class="ltn-frame ltn-frame--success p-5 space-y-2"> <p class="m-0 ltn-prose">Tu te lèves. Tu ne dis rien — tu n'en as pas besoin. Le silence pèse plus que n'importe quelle menace.</p> <p class="m-0 ltn-prose"><<print _c.displayName>> pâlit et sort l'argent. Intégralité payée.</p> <p class="m-0 text-sm font-semibold text-emerald">Intimidation réussie — dette de session effacée.</p> </div> <<else>> <div class="ltn-frame ltn-frame--danger p-5"> <p class="m-0 ltn-prose">La pression rate. <<print _c.displayName>> se crispe — le stress monte, pas l'argent.</p> </div> <</if>> <<set $debt_index to $debt_index + 1>> <div class="ltn-footer-nav"> <span class="navbtn btn-primary"><<link `setup.t("common.next")`>><<goto "Debt Settlement Start">><</link>></span> </div> </div>
<<set _c to setup.characters[$debt_current_char]>> <<set _control to setup.getControl($debt_current_char)>> <<set _stress to setup.getCharVar($debt_current_char, "stress")>> <<set _req to setup.characters[$debt_current_char].arrangementReq>> <<if setup.canArrange($debt_current_char)>> <<goto "Arrangement Scene">> <<else>> <div class="ltn-shell"> <<print setup.renderPageHeader(setup.t("debt.arrangement_refused"), _c.displayName, setup.tf("Conditions", "Requirements"))>> <div class="ltn-frame ltn-frame--warn p-5"> <p class="m-0 mb-3 text-ink-soft">Les conditions ne sont pas réunies.</p> <ul class="m-0 list-disc space-y-1 pl-5 text-sm text-ink-soft"> <li>Contrôle requis : <<print setup.gameData.control.arrangementMin>> ★ (actuel : <<print _control>> ★)</li> <li>Stress requis : <<print _req.stress>>% (actuel : <<print _stress>>%)</li> <li>Réputation requise : <<print (_req.reputationPoints != null ? _req.reputationPoints : _req.reputation)>> pts (actuelle : <<print setup.getReputationPoints()>> pts)</li> </ul> </div> <div class="ltn-footer-nav"> <span class="navbtn btn-secondary"><<link `setup.t("common.back")`>><<goto "Debt Settlement Character">><</link>></span> </div> </div> <</if>>
<<set _c to setup.characters[$debt_current_char]>> <div class="ltn-shell"> <<print setup.renderPageHeader(setup.t("debt.let_ride"), _c.displayName, setup.t("debt.debt"))>> <div class="ltn-frame ltn-frame--danger p-5 space-y-2"> <p class="m-0 ltn-prose">Tu laisses la dette s'accumuler. <<print _c.displayName>> hoche la tête, soulagé(e) pour l'instant.</p> <p class="m-0 ltn-prose">Mais les dettes non réglées ont un prix.</p> </div> <<run setup.addReputation((setup.gameData.debt && setup.gameData.debt.letRideReputation) || -25, "debt_let_ride")>> <<run setup.applyControl($debt_current_char, -1)>> <<run setup.setCharVar($debt_current_char, "relationship", setup.getCharVar($debt_current_char, "relationship") + 5)>> <div class="ltn-alert ltn-alert--danger">Réputation −25 pts | Contrôle −1</div> <<set $debt_index to $debt_index + 1>> <div class="ltn-footer-nav"> <span class="navbtn btn-primary"><<link `setup.t("common.next")`>><<goto "Debt Settlement Start">><</link>></span> </div> </div>
/* Fallback legacy (PNJ sans scènes narratives). Marco → Recovery Special / Narrative Scene. */ <<set _char to $debt_current_char>> <<set _c to setup.characters[_char]>> <<set _arr to _c && _c.arrangement>> <<set _nextArr to (!_arr && setup.getNextAvailableFavor) ? setup.getNextAvailableFavor(_char) : null>> <<if !_arr && _nextArr>> <<set $narrative_context to ($narrative_context || "recovery")>> <<set $recovery_char to _char>> <<set $narrative_scene_id to _nextArr.id>> <<goto "Narrative Scene">> <<elseif !_arr>> <<goto "Recovery Result">> <<else>> <<run setup.applyArrangement(_char)>> <div class="ltn-shell"> <<print setup.renderPageHeader(_arr.title, _c.displayName, setup.t("arr.eyebrow"))>> /* Image d'ouverture obligatoire */ <<print setup._narrativeMediaHTML({ type: "image", src: (_c.image || ("images/characters/" + _char + ".webp")), alt: _c.displayName, fallbackSrc: "images/backgrounds/office_day.webp" }, { hero: true })>> <<print setup.renderCharStatus(_char)>> <<if _arr.opening !== "">> <div class="ltn-frame p-4 my-3"><p class="m-0 ltn-prose"><<print _arr.opening>></p></div> <</if>> <<if _arr.dialogue !== "">> <<print setup.renderDialogueHTML(_char, _arr.dialogue)>> <</if>> <<if _arr.flavor !== "">> <p class="ltn-prose"><<print _arr.flavor>></p> <</if>> <div class="ltn-frame p-5"> <<print _arr.adultBody || _arr.safeBody || "">> </div> <div class="ltn-alert ltn-alert--success"><<print _arr.outcome>></div> <<set $debt_index to $debt_index + 1>> <div class="ltn-footer-nav"> <span class="navbtn btn-primary"><<link `setup.t("common.next")`>><<goto "Debt Settlement Start">><</link>></span> </div> </div> <</if>>
/* Personnage retiré du cast final */ <<goto "Hub">>
<<set $event_betrayal_marco to true>> <div class="ltn-shell"> <<print setup.renderPageHeader(setup.t("event.betrayal_title"), setup.tf("Parking du club", "Club parking lot"), setup.tf("Événement", "Event"))>> <p class="ltn-prose"><<= setup.tf("Marco a parlé. Pas beaucoup — juste assez. Un détective privé embauché par un concurrent a des notes avec ton nom. Il t'attend dans le parking, larmes aux yeux.", "Marco talked. Not much — just enough. A private eye hired by a rival has notes with your name. He's waiting in the parking lot, eyes wet.") >></p> <<print setup.renderDialogueHTML("marco", setup.tf("Darius, je... ils m'ont forcé. Je leur ai dit où se passent les parties. Je suis désolé.", "Darius, I... they forced me. I told them where the games are. I'm sorry."))>> <div class="ltn-choices favor-scene__choices"> <span class="navbtn btn-primary btn-block"><<link `setup.t("event.punish_debt")` "Event Betrayal Punish">><</link>></span> <span class="navbtn btn-secondary btn-block"><<link `setup.t("event.use_agent")` "Event Betrayal Turn">><</link>></span> <span class="navbtn btn-ghost btn-block"><<link `setup.t("event.eliminate")` "Event Betrayal Ban">><</link>></span> </div> </div>
<<run setup.setCharVar("marco", "debt", setup.getCharVar("marco", "debt") + 3000)>> <<run setup.setCharVar("marco", "stress", setup.clamp(setup.getCharVar("marco", "stress") + 20, 0, 100))>> <<run setup.addReputation(-15, "betrayal_punish_marco")>> <div class="ltn-shell"> <<print setup.renderPageHeader(setup.t("event.punish"), "Marco Rossi", setup.tf("Événement", "Event"))>> <<print setup.renderDialogueHTML("darius", setup.tf("Trois mille de plus. Et tu parleras plus jamais.", "Three thousand more. And you never talk again."))>> <p class="ltn-prose"><<= setup.tf("Marco hoche la tête, détruit.", "Marco nods, destroyed.") >></p> <div class="ltn-footer-nav"> <span class="navbtn btn-primary"><<link `setup.t("common.back_hub")` "Hub">><</link>></span> </div> </div>
<<run setup.doSkillCheck("intimidation", 14)>> <div class="ltn-shell"> <<print setup.renderPageHeader(setup.t("event.double_agent"), "Marco Rossi", setup.tf("Intimidation", "Intimidation"))>> <<intimidation_check>> <<if $last_check_success>> <<run setup.addReputation(50, "betrayal_turn_marco")>> <<run setup.setCharVar("marco", "relationship", -30)>> <div class="ltn-frame ltn-frame--success p-5 space-y-2"> <p class="m-0 ltn-prose"><<= setup.tf("Tu retournes Marco. Il te rapportera ce que les concurrents préparent.", "You flip Marco. He'll report what the rivals are planning.") >></p> <p class="m-0 text-sm font-semibold text-emerald"><<= setup.tf("Marco est maintenant ton espion. Réputation +50 points.", "Marco is now your spy. Reputation +50 points.") >></p> </div> <<else>> <<run setup.setCharVar("marco", "available", false)>> <<run setup.setCharVar("marco", "poker_circle", false)>> <<run setup.addReputation(-20, "betrayal_lost_marco")>> <div class="ltn-frame ltn-frame--danger p-5 space-y-2"> <p class="m-0 ltn-prose"><<= setup.tf("Marco s'enfuit dans la nuit. Tu ne le reverras plus.", "Marco flees into the night. You won't see him again.") >></p> <p class="m-0 text-sm font-semibold text-crimson"><<= setup.tf("Marco a disparu. Réputation -20 points.", "Marco is gone. Reputation -20 points.") >></p> </div> <</if>> <div class="ltn-footer-nav"> <span class="navbtn btn-ghost"><<link `setup.t("common.back_hub")` "Hub">><</link>></span> </div> </div>
<<run setup.setCharVar("marco", "available", false)>> <<run setup.setCharVar("marco", "poker_circle", false)>> <<run setup.addReputation(30, "betrayal_ban_marco")>> <div class="ltn-shell"> <<print setup.renderPageHeader(setup.t("event.banish"), "Marco Rossi", setup.tf("Événement", "Event"))>> <<print setup.renderDialogueHTML("darius", setup.tf("Dégage. Et prie pour que je ne te retrouve pas.", "Get out. And pray I never find you again."))>> <p class="ltn-prose"><<= setup.tf("Marco est banni de la table. Pour toujours.", "Marco is banned from the table. Forever.") >></p> <div class="ltn-footer-nav"> <span class="navbtn btn-primary"><<link `setup.t("common.back_hub")` "Hub">><</link>></span> </div> </div>
<<set $ending_reached to true>> <div class="ltn-shell"> <div class="title-screen"> <h1>GAME OVER</h1> <p class="tagline"><<= setup.tf("Le requin dévoré", "The shark, eaten") >></p> </div> <div class="result-card result-card--lose"> <<= setup.tf("Plus d'argent. Plus de crédibilité. Tes créanciers te rachètent — table, club, honneur. Tu n'as pas le choix.<br><br>Tu n'es plus le requin. Tu es la proie.", "No money left. No credibility. Your creditors buy you out — table, club, honor. You have no choice.<br><br>You're not the shark anymore. You're the prey.") >> </div> <div class="ltn-footer-nav"> <span class="navbtn btn-primary"><<link `setup.t("end.restart")` "Start">><</link>></span> </div> </div>
<<set $ending_reached to true>> <div class="ltn-shell"> <div class="title-screen"> <h1><<= setup.tf("VICTOIRE", "VICTORY") >></h1> <p class="tagline"><<= setup.tf("L'Empire de la Table Noire", "Empire of the Black Table") >></p> <span class="version-badge"><<= setup.tf("Fin v0.11", "Ending v0.11") >></span> </div> <div class="result-card result-card--win"> <<= setup.tf("Le ladder est gravé. Des dettes transformées en loyauté, en peur, en pouvoir. La table noire est un trône.<br><br>Darius \"The Shark\" King n'est plus un petit caïd. Il devient une légende.", "The ladder is carved. Debts turned into loyalty, fear, power. The black table is a throne.<br><br>Darius \"The Shark\" King is no longer a small-time boss. He becomes a legend.") >> </div> <div class="ltn-footer-nav"> <span class="navbtn btn-primary"><<link `setup.t("end.restart")` "Start">><</link>></span> </div> </div>
<<set _cid to $control_notify_char>> <<set _lvl to $control_notify_level>> <<set _c to setup.characters[_cid]>> <div class="ltn-shell"> <div class="ltn-frame ltn-frame--gold ltn-notify"> <span class="ltn-badge"><<= setup.tf("Nouveau seuil", "New threshold") >></span> <h2 class="ltn-notify__title"><<print _c.displayName>></h2> <p class="ltn-notify__stars"><<print setup.controlStars(setup.getControl(_cid), setup.getControlCap(_cid))>></p> <<if _lvl is 3>> <p class="ltn-notify__text"><<= setup.tf('<strong class="text-gold-light">Pris au piège.</strong> Arrangements spéciaux débloqués si le stress est suffisant.', '<strong class="text-gold-light">Cornered.</strong> Special arrangements unlock if stress is high enough.') >></p> <<elseif _lvl is 4>> <p class="ltn-notify__text"><<= setup.tf('<strong class="text-gold-light">Soumis.</strong> Nouveau contenu et rappels au bureau possibles.', '<strong class="text-gold-light">Broken in.</strong> New content and office callbacks possible.') >></p> <<else>> <p class="ltn-notify__text"><<= setup.tf('<strong class="text-gold-light">Sous ton emprise.</strong> Ce personnage t\'appartient presque entièrement.', '<strong class="text-gold-light">Under your thumb.</strong> This character is almost entirely yours.') >></p> <</if>> </div> <<set $control_notify_char to "">> <<set $control_notify_level to 0>> <div class="menu-hub ltn-menu"> <span class="navbtn btn-primary btn-block"><<link `setup.t("common.continue")` "Hub">><</link>></span> </div> </div>
<div class="ltn-shell"> <<print setup.renderPageHeader(setup.t("network.title"), setup.t("network.subhead"), setup.t("debt.control"))>> <div class="ltn-quote"><<= setup.t("network.quote") >></div> <div class="space-y-3"> <<for _cid range setup.characterIds>> <<if setup.hasMetCharacter(_cid)>> <<set _c to setup.characters[_cid]>> <<set _ctrl to setup.getControl(_cid)>> <<set _stress to setup.getCharVar(_cid, "stress")>> <<set _arrMin to (setup.gameData.control && setup.gameData.control.arrangementMin) || 3>> <<set _netHot to (_ctrl gte _arrMin)>> <<if _netHot>> <div class="ltn-frame ltn-network ltn-network--hot network-card--unlocked"> <<else>> <div class="ltn-frame ltn-network"> <</if>> <div class="ltn-network__head"> <strong class="ltn-network__name"><<print _c.displayName>></strong> <span class="ltn-pill ltn-pill--ctrl control-stars control-stars--lg"><<print setup.controlStars(_ctrl, setup.getControlCap(_cid))>></span> </div> <div class="ltn-network__meta"> <span><<print setup.controlLabel(_ctrl)>></span> <span><<= setup.t("debt.stress") >> <<print _stress>>%</span> <span><<= setup.t("debt.debt") >> <<print setup.formatMoney(setup.getCharVar(_cid, "debt"))>></span> </div> <div class="ltn-network__tags"> <<if setup.getCharVar(_cid, "scene_3")>><span class="ltn-tag ltn-tag--on"><<= setup.t("arr.eyebrow") >></span><<else>><span class="ltn-tag"><<= setup.t("arr.eyebrow") >></span><</if>> <<if setup.getCharVar(_cid, "scene_4")>><span class="ltn-tag ltn-tag--on"><<= setup.tf("Scène ★★★★", "Scene ★★★★") >></span><<else>><span class="ltn-tag"><<= setup.tf("Scène ★★★★", "Scene ★★★★") >></span><</if>> <<if setup.getCharVar(_cid, "scene_5")>><span class="ltn-tag ltn-tag--on"><<= setup.tf("Fin arc", "Arc end") >></span><<else>><span class="ltn-tag"><<= setup.tf("Fin arc", "Arc end") >></span><</if>> </div> </div> <</if>> <</for>> </div> <div class="ltn-footer-nav"> <span class="navbtn btn-secondary btn-block"><<link `setup.t("common.back_hub")` "Hub">><</link>></span> </div> </div>
/* Compat : anciennes intrigues retirées → hub */ <<goto "Hub">>
<<run setup.ensureEmpireState()>> <<run setup.rollAudiencesIfNeeded()>> <<set _n to setup.getAudienceCount()>> <<set _isAud to setup.isAudienceDay()>> <div class="ltn-shell audience-desk"> <<print setup.renderPageHeader(setup.t("audience.desk"), setup.tf("Bureau du patron · ", "Boss's office · ") + setup.getDayName() + setup.tf(" · Jour ", " · Day ") + setup.getAbsoluteDay(), setup.tf("Empire", "Empire"))>> <div class="audience-desk__bar" role="status"> <div class="audience-desk__bar-text"> <span class="audience-desk__bar-label"><<= setup.t("audience.queue") >></span> <<if _isAud>> <span class="audience-desk__bar-hint"><<= _n > 0 ? setup.tf(_n + " pétitionnaire(s) dans le couloir", _n + " petitioner(s) in the hall") : setup.tf("Jour d'audience — file vide pour l'instant", "Audience day — line empty for now") >></span> <<else>> <span class="audience-desk__bar-hint"><<= setup.tf("Pas de réception aujourd'hui (tous les 2 jours)", "No reception today (every 2 days)") >></span> <</if>> </div> <div class="audience-desk__bar-meta"> <span class="audience-desk__chip audience-desk__chip--day"><<= setup.t("common.day") >></span> <<if _isAud>> <span class="audience-desk__chip audience-desk__chip--wait"><<= _n >> <<= setup.tf("en attente", "waiting") >></span> <<else>> <span class="audience-desk__chip"><<= setup.tf("Fermé", "Closed") >></span> <</if>> <span class="audience-desk__chip audience-desk__chip--cash"><<print setup.formatMoney($money)>></span> </div> </div> <<if !_isAud>> <section class="audience-desk__section"> <div class="audience-panel audience-panel--info"> <p class="audience-panel__kicker"><<= setup.tf("Calendrier pègre", "Underworld calendar") >></p> <p class="audience-panel__body"><<= setup.tf("Les audiences ont lieu <strong>tous les 2 jours</strong>. Aujourd'hui, la rue sait que le Requin ne reçoit pas. Reviens demain — ou fais payer ceux qui te doivent déjà.", "Audiences are held <strong>every 2 days</strong>. Today the street knows the Shark isn't receiving. Come back tomorrow — or make those who already owe you pay.") >></p> </div> </section> <<elseif _n <= 0>> <section class="audience-desk__section"> <div class="audience-panel audience-panel--empty"> <p class="audience-panel__kicker"><<= setup.tf("File vide", "Empty line") >></p> <p class="audience-panel__body"><<= setup.tf("Soit tu as tout traité, soit personne n'a osé frapper. Le silence est aussi une forme de respect.", "Either you cleared everyone, or nobody dared knock. Silence is also a form of respect.") >></p> </div> </section> <<else>> <section class="audience-desk__section"> <blockquote class="audience-desk__quote"><<= setup.tf("On ne frappe pas à ta porte pour bavarder. On vient mendier de l'air — et tu vends de l'oxygène au prix du sang.", "They don't knock on your door to chat. They come begging for air — and you sell oxygen at blood price.") >></blockquote> <p class="audience-desk__lead"><strong><<= _n >></strong> <<= setup.tf("personne(s) dans le couloir. Personne ne fume sans permission.", "person(s) in the hall. Nobody smokes without permission.") >></p> <div class="audience-queue"> <<for _aid range $audience_queue>> <<capture _aid>> <div class="audience-queue__item"> <<print setup.renderAudienceCardHTML(_aid)>> <div class="audience-card__actions"> <span class="navbtn btn-primary"><<link `setup.getAudienceReceiveLabel(_aid)`>><<run setup.beginAudience(_aid)>><<goto "Audience Scene">><</link>></span> <span class="navbtn btn-ghost"><<link `setup.t("audience.dismiss")`>><<run setup.dismissAudience(_aid)>><<goto "Audience Result">><</link>></span> </div> </div> <</capture>> <</for>> </div> </section> <</if>> <nav class="audience-desk__nav ltn-footer-nav"> <span class="navbtn btn-ghost"><<link `setup.t("common.back_hub")` "Hub">><</link>></span> </nav> </div>
/* Dialogues data-driven : js/data/audience_dialogues.js */ <<run setup.ensureEmpireState()>> <<if typeof LTN_applyGameDataCatalog === "function">><<run LTN_applyGameDataCatalog()>><</if>> <<set _cid to $audience_current || "">> <<if !_cid || !setup.characters[_cid]>> <<goto "Audience Desk">> <</if>> <<if !$audience_request>><<set $audience_request to setup.getAudienceRequestType(_cid)>><</if>> <div class="ltn-shell audience-scene"> <<print setup.renderAudienceSceneHTML(_cid, $audience_request)>> <<include "Audience Choices">> </div>
/* Compat : même moteur que Audience Scene */ <<goto "Audience Scene">>
/* Fragment inclus dans les scènes d'audience — un seul acte : accorder le prêt */ <<set _cid to $audience_current || "">> <<set $audience_request to "loan">> <<if $loan_draft>><<set $loan_draft.charId to _cid>><</if>> <div class="audience-choices debt-choices"> <div class="ltn-choice debt-choice debt-choice--arrangement"> <span class="navbtn btn-primary btn-block"><<link `setup.t("audience.grant_loan")` "Loan Terms">><</link>></span> </div> </div> <nav class="audience-desk__nav ltn-footer-nav"> <span class="navbtn btn-ghost"><<link `setup.t("audience.queue")` "Audience Desk">><</link>></span> </nav>
<div class="ltn-shell audience-result"> <<print setup.renderPageHeader(setup.t("audience.closed"), "Le bureau redevient silencieux", "Empire")>> <div class="ltn-frame ltn-frame--success p-5"> <p class="m-0 ltn-prose"><<print $last_audience_msg>></p> </div> <div class="ltn-footer-nav"> <<if setup.getAudienceCount() > 0>> <span class="navbtn btn-primary"><<link `setup.t("audience.queue")` "Audience Desk">><</link>></span> <<else>> <span class="navbtn btn-primary"><<link `setup.t("common.hub")` "Hub">><</link>></span> <</if>> <span class="navbtn btn-ghost"><<link `setup.t("common.hub")` "Hub">><</link>></span> </div> </div>
<<run setup.ensureEmpireState()>> <<set _cid to ($loan_draft && $loan_draft.charId) || $audience_current || "">> <<if !_cid>><<goto "Audience Desk">><</if>> <<set $loan_draft.charId to _cid>> <<run setup.clampLoanDraftAmount()>> <<set _c to setup.characters[_cid]>> <<set _lim to setup.getLoanDraftLimits()>> <<set _prev to setup.previewDraftDueTomorrow()>> <div class="ltn-shell audience-scene"> <<print setup.renderPageHeader(setup.t("loan.title"), _c.displayName + " · coffre " + setup.formatMoney($money), "Empire")>> <div class="ltn-quote">Simple : tu verses, ils te doivent. Les intérêts font le reste.</div> <div class="ltn-panel my-3"> <p class="ltn-panel-kicker">Montant versé</p> <p class="ltn-panel-body !text-2xl font-bold text-gold-light"><<print setup.formatMoney($loan_draft.amount)>></p> <p class="text-sm text-ink-muted">Intérêt : <<print _prev.interestPct>>% — dette immédiate <strong class="text-ink"><<print setup.formatMoney(_prev.remaining)>></strong>.</p> <p class="text-sm text-ink-muted mt-1"><<= setup.t("loan.limits", { min: setup.formatMoney(_lim.min), max: setup.formatMoney(_lim.max) }) >></p> <div class="ltn-actions ltn-actions--start mt-2"> <<if !_lim.atMin>> <span class="navbtn btn-secondary"><<link `setup.t("loan.minus_500")`>><<run setup.adjustLoanDraftAmount(-500)>><<goto "Loan Terms">><</link>></span> <<else>> <span class="navbtn btn-secondary is-disabled" aria-disabled="true"><<= setup.t("loan.minus_500") >></span> <</if>> <<if !_lim.atMax>> <span class="navbtn btn-secondary"><<link `setup.t("loan.plus_500")`>><<run setup.adjustLoanDraftAmount(500)>><<goto "Loan Terms">><</link>></span> <span class="navbtn btn-secondary"><<link `setup.t("loan.plus_1000")`>><<run setup.adjustLoanDraftAmount(1000)>><<goto "Loan Terms">><</link>></span> <<else>> <span class="navbtn btn-secondary is-disabled" aria-disabled="true"><<= setup.t("loan.plus_500") >></span> <span class="navbtn btn-secondary is-disabled" aria-disabled="true"><<= setup.t("loan.plus_1000") >></span> <</if>> </div> </div> <div class="ltn-panel ltn-panel--compact my-3"> <p class="ltn-panel-kicker">Dû demain (sans paiement)</p> <p class="ltn-panel-body !text-xl font-bold text-gold-light"><<print setup.formatMoney(_prev.dueTomorrow)>></p> <p class="text-sm text-ink-muted m-0">+<<print setup.formatMoney(_prev.creep)>> d'intérêts / jour (<<= _prev.dailyRatePct != null ? _prev.dailyRatePct : 5 >> %) si rien n'est payé.</p> </div> <div class="ltn-footer-nav"> <span class="navbtn btn-primary"><<link `setup.t("loan.sign")`>><<goto "Loan Confirm">><</link>></span> <span class="navbtn btn-ghost"><<link `setup.t("common.cancel")` "Audience Desk">><</link>></span> </div> </div>
<<run setup.ensureEmpireState()>> <<set _res to setup.grantLoanFromDraft()>> <<if _res.ok>> <<run setup.finishAudienceSlot($loan_draft.charId)>> <<set $last_audience_msg to _res.msg>> <<else>> <<set $last_audience_msg to _res.msg>> <</if>> <div class="ltn-shell"> <<print setup.renderPageHeader(_res.ok ? setup.tf("Prêt scellé", "Loan sealed") : setup.tf("Prêt refusé", "Loan refused"), setup.tf("Coffre du club", "Club vault"), setup.tf("Empire", "Empire"))>> <<if _res.ok>> <div class="ltn-frame ltn-frame--success p-5"> <p class="m-0 ltn-prose"><<print $last_audience_msg>></p> </div> <<else>> <div class="ltn-frame ltn-frame--danger p-5"> <p class="m-0 ltn-prose"><<print $last_audience_msg>></p> </div> <</if>> <<if _res.ok && _res.loan>> <<set _dueT to setup.getLoanDueTomorrow(_res.loan)>> <<set _creep to setup.getLoanDailyCreepAmount(_res.loan)>> <div class="ltn-panel ltn-panel--compact mt-3"> <p class="ltn-panel-body text-sm">Intérêt : <<print _res.loan.interestPct>>% · dette : <<print setup.formatMoney(_res.loan.remaining)>></p> <p class="ltn-panel-body text-sm mt-2"><strong class="text-gold-light">Dû demain :</strong> <<print setup.formatMoney(_dueT)>> <span class="text-ink-muted">(+<<print setup.formatMoney(_creep)>> / jour)</span></p> </div> <</if>> <div class="ltn-footer-nav"> <span class="navbtn btn-primary"><<link `setup.t("common.hub")` "Hub">><</link>></span> <span class="navbtn btn-secondary"><<link `setup.t("audience.desk")` "Audience Desk">><</link>></span> <span class="navbtn btn-ghost"><<link `setup.t("common.hub")` "Hub">><</link>></span> </div> </div>
<<run setup.ensureEmpireState()>> <<set $audience_current to "tasha">> <<if !$audience_request>><<set $audience_request to setup.getAudienceRequestType("tasha")>><</if>> <<goto "Audience Scene">>
<<run setup.ensureEmpireState()>> <<set $audience_current to "raymond">> <<if !$audience_request>><<set $audience_request to setup.getAudienceRequestType("raymond")>><</if>> <<goto "Audience Scene">>
<<silently>> <<run setup.ensureEmpireState()>> <<run setup.checkReputationLadder({ silent: true })>> <<set _circle to setup.listPokerCircle()>> <<set _locked to setup.listLockedPokerCandidates()>> <</silently>> <div class="ltn-shell audience-desk"> <<print setup.renderPageHeader(setup.t("circle.title"), setup.t("circle.sub"), setup.t("circle.empire"))>> <div class="audience-desk__bar" role="status"> <div class="audience-desk__bar-text"> <span class="audience-desk__bar-label"><<= setup.t("circle.guests") >></span> <span class="audience-desk__bar-hint"><<= setup.t("circle.guests_hint") >></span> </div> <span class="audience-desk__chip"><<= _circle.length >> <<= setup.t("circle.members") >></span> </div> <<if _circle.length is 0>> <div class="audience-panel audience-panel--empty"> <p class="audience-panel__kicker"><<= setup.t("circle.empty") >></p> <p class="audience-panel__body"><<= setup.t("circle.empty_body") >></p> </div> <<else>> <div class="audience-queue"> <<for _i to 0; _i lt _circle.length; _i++>> <<set _id to _circle[_i]>> <<set _c to setup.characters[_id]>> <div class="audience-queue__item"> <<print setup.renderAudienceCardHTML(_id)>> <div class="audience-card__actions"> <<capture _id>> <span class="navbtn btn-secondary"><<link `setup.t("circle.revoke")`>><<run setup.revokePokerCircle(_id)>><<goto "Circle Desk">><</link>></span> <</capture>> </div> </div> <</for>> </div> <</if>> <<if _locked.length > 0>> <div class="audience-desk__bar mt-6" role="status"> <div class="audience-desk__bar-text"> <span class="audience-desk__bar-label"><<= setup.t("circle.off_table") >></span> <span class="audience-desk__bar-hint"><<= setup.t("circle.off_table_hint") >></span> </div> </div> <div class="audience-queue"> <<for _i to 0; _i lt _locked.length; _i++>> <<set _id to _locked[_i]>> <div class="audience-queue__item audience-queue__item--locked"> <<print setup.renderLockedCharacterCardHTML(_id)>> <<if setup.canReinstatePokerCircle(_id)>> <div class="audience-card__actions"> <<capture _id>> <span class="navbtn btn-primary"><<link `setup.t("circle.reintegrate")`>><<run setup.reinstatePokerCircle(_id)>><<goto "Circle Desk">><</link>></span> <</capture>> </div> <</if>> </div> <</for>> </div> <</if>> <nav class="audience-desk__nav ltn-footer-nav"> <span class="navbtn btn-ghost"><<link `setup.t("common.back_hub")` "Hub">><</link>></span> <span class="navbtn btn-secondary"><<link `setup.t("hub.ladder")` "Reputation Ladder">><</link>></span> </nav> </div>
<<run setup.ensureEmpireState()>> <<set _cid to $recovery_char>> <<if !_cid || !setup.characters[_cid] || !setup.isCollectibleDebtor(_cid)>> <<goto "Debt Ledger">> <</if>> /* Intervalle perso : pas de menu hors proposition (sauf file du jour en cours) */ <<if !setup.canOpenRecoveryMenu(_cid)>> <<goto "Debt Ledger">> <</if>> <<set _c to setup.characters[_cid]>> <<set _cCash to setup.getRecoveryCost("takeCash")>> <<set _cRep to setup.getRecoveryCost("claimRep")>> <<set _cPD to setup.getRecoveryCost("claimPD")>> <<set _cCtrl to setup.getRecoveryCost("claimControl")>> <<set _cSpecial to setup.getRecoveryCost("special")>> <<set _cRide to setup.getRecoveryCost("letRide")>> <<set _canCash to setup.canUseRecoveryAction("takeCash", _cid)>> <<set _canRep to setup.canUseRecoveryAction("claimRep", _cid)>> <<set _canPD to setup.canUseRecoveryAction("claimPD", _cid)>> <<set _canCtrl to setup.canUseRecoveryAction("claimControl", _cid)>> <<set _canSpecial to setup.canUseRecoveryAction("special", _cid)>> <<set _canRide to setup.canUseRecoveryAction("letRide", _cid)>> <<set _alreadyDone to setup.hasRecoveryActionThisPhase(_cid)>> <<set _phaseLabel to $time_phase is "night" ? setup.t("recovery.phase_night") : setup.t("recovery.phase_day")>> <<set _pd to setup.t("common.pd")>> /* Libellés pré-composés (pas de <<print>> dans [[…]]) */ <<set _lCash to setup.t("recovery.take_cash") + " · " + _cCash + " " + _pd>> <<set _lRep to setup.t("recovery.claim_rep") + " · " + _cRep + " " + _pd>> <<set _lPD to _cPD > 0 ? (setup.t("recovery.claim_pd") + " · " + _cPD + " " + _pd) : (setup.t("recovery.claim_pd") + " · " + setup.t("recovery.free"))>> <<set _lCtrl to setup.t("recovery.claim_control") + " · " + _cCtrl + " " + _pd>> <<set _lSpecial to setup.t("recovery.special") + " · " + _cSpecial + " " + _pd>> <<set _lRide to _cRide > 0 ? (setup.t("recovery.let_ride") + " · " + _cRide + " " + _pd) : (setup.t("recovery.let_ride") + " · " + setup.t("recovery.free"))>> <div class="ltn-shell audience-scene"> <<print setup.renderPageHeader(setup.t("recovery.title", { name: _c.displayName }), setup.t("debt.debt") + " " + setup.formatMoney(setup.getCharVar(_cid, "debt")), setup.tf("Pègre", "Underworld"))>> <<print setup.renderCharStatus(_cid)>> <div class="audience-panel audience-panel--demand"> <p class="audience-panel__kicker"><<= setup.t("recovery.you_boss") >></p> <<if _alreadyDone>> <p class="audience-panel__body"><<= setup.t("recovery.locked_phase", { phase: _phaseLabel }) >></p> <<else>> <p class="audience-panel__body"><<= setup.t("recovery.choose") >></p> <</if>> </div> <div class="audience-choices debt-choices recovery-choices"> <<if _alreadyDone>> <div class="recovery-choice recovery-choice--locked"> <span class="recovery-choice__label"><<= setup.t("recovery.locked_label") >></span> <span class="recovery-choice__cost"><<= setup.t("recovery.locked_cost") >></span> </div> <<else>> <<if _canCash.ok>> <div class="ltn-choice debt-choice debt-choice--cash"> <span class="navbtn btn-block"><<link _lCash "Recovery Take Cash">><</link>></span> </div> <<else>> <div class="recovery-choice recovery-choice--locked"> <span class="recovery-choice__label"><<= setup.t("recovery.take_cash") >></span> <span class="recovery-choice__cost"><<print _canCash.msg>></span> </div> <</if>> <<if _canRep.ok>> <div class="ltn-choice debt-choice debt-choice--pressure"> <span class="navbtn btn-block"><<link _lRep "Recovery Claim Rep">><</link>></span> </div> <<else>> <div class="recovery-choice recovery-choice--locked"> <span class="recovery-choice__label"><<= setup.t("recovery.claim_rep") >></span> <span class="recovery-choice__cost"><<print _canRep.msg>></span> </div> <</if>> <<if _canPD.ok>> <div class="ltn-choice debt-choice debt-choice--pressure"> <span class="navbtn btn-block"><<link _lPD "Recovery Claim PD">><</link>></span> </div> <<else>> <div class="recovery-choice recovery-choice--locked"> <span class="recovery-choice__label"><<= setup.t("recovery.claim_pd") >></span> <span class="recovery-choice__cost"><<print _canPD.msg>></span> </div> <</if>> <<if _canCtrl.ok>> <div class="ltn-choice debt-choice debt-choice--pressure"> <span class="navbtn btn-block"><<link _lCtrl "Recovery Claim Control">><</link>></span> </div> <<else>> <div class="recovery-choice recovery-choice--locked"> <span class="recovery-choice__label"><<= setup.t("recovery.claim_control") >></span> <span class="recovery-choice__cost"><<print _canCtrl.msg>></span> </div> <</if>> <<if _canSpecial.ok>> <div class="ltn-choice debt-choice debt-choice--arrangement"> <span class="navbtn btn-block"><<link _lSpecial "Recovery Special">><</link>></span> </div> <<else>> <div class="recovery-choice recovery-choice--locked"> <span class="recovery-choice__label"><<= setup.t("recovery.special") >></span> <span class="recovery-choice__cost"><<print _canSpecial.msg>></span> </div> <</if>> <<if _canRide.ok>> <div class="ltn-choice debt-choice debt-choice--ride"> <span class="navbtn btn-block"><<link _lRide "Recovery Let Ride">><</link>></span> </div> <<else>> <div class="recovery-choice recovery-choice--locked"> <span class="recovery-choice__label"><<= setup.t("recovery.let_ride") >></span> <span class="recovery-choice__cost"><<print _canRide.msg>></span> </div> <</if>> <</if>> </div> </div>
<<run setup.recoveryTakeCash($recovery_char)>> <<goto "Recovery Result">>
<<run setup.recoveryClaimRep($recovery_char)>> <<goto "Recovery Result">>
<<run setup.recoveryClaimPD($recovery_char)>> <<goto "Recovery Result">>
<<run setup.recoveryClaimControl($recovery_char)>> <<goto "Recovery Result">>
<<run setup.recoveryLetRide($recovery_char)>> <<goto "Recovery Result">>
<<set _res to setup.recoverySpecialDeal($recovery_char)>> <<if _res.gotoNarrative && _res.sceneId>> <<set $narrative_scene_id to _res.sceneId>> <<set $narrative_context to "recovery">> <<set $recovery_char to $recovery_char>> <<goto "Narrative Scene">> <<elseif _res.gotoArrangement>> <<set $debt_current_char to $recovery_char>> <<goto "Arrangement Scene">> <<else>> <<goto "Recovery Result">> <</if>>
<<if $last_recovery_ok>><<run setup.markRecoveryHandled($recovery_char)>><</if>> <<set _fromDebt to ($narrative_context === "debt")>> <<set _fromNarr to ($narrative_context === "recovery" || $narrative_context === "debt" || $narrative_context === "debug")>> <div class="ltn-shell audience-result"> <<print setup.renderPageHeader(_fromDebt ? "Règlement" : "Recouvrement", setup.characters[$recovery_char] ? setup.characters[$recovery_char].displayName : "", "Résultat")>> <<if $recovery_char && setup.characters[$recovery_char]>> <<print setup.renderCharStatus($recovery_char)>> <</if>> <div class="audience-panel audience-panel--result<<if $last_recovery_ok>> audience-panel--result-ok<<else>> audience-panel--result-fail<</if>>"> <p class="audience-panel__kicker"><<if $last_recovery_ok>>Action réussie<<else>>Échec / bloqué<</if>></p> <p class="audience-panel__body"><<print $last_recovery_msg || "L'affaire est close — pour l'instant.">></p> </div> <<intimidation_check>> <<if $last_recovery_effects && $last_recovery_effects.length > 0>> <div class="recovery-fx-panel" role="region" aria-label="Effets appliqués"> <p class="recovery-fx-panel__title">Effets appliqués</p> <<print setup.renderRecoveryEffectsHTML()>> </div> <<elseif $last_recovery_ok>> <div class="recovery-fx-panel recovery-fx-panel--empty"> <p class="recovery-fx-panel__title">Effets appliqués</p> <p class="recovery-fx-panel__empty">Aucun changement numérique mesurable — l'action reste narrative.</p> </div> <</if>> <nav class="audience-desk__nav ltn-footer-nav"> <<if _fromDebt>> <span class="navbtn btn-primary"><<link `setup.t("common.next")` "Debt Settlement Start">><</link>></span> <<elseif !$last_recovery_ok>> <span class="navbtn btn-secondary"><<link `setup.t("recovery.same_target")` "Recovery Menu">><</link>></span> <span class="navbtn btn-ghost"><<link `setup.t("common.hub")` "Hub">><</link>></span> <<else>> <span class="navbtn btn-primary"><<link `setup.t("common.hub")` "Hub">><</link>></span> <span class="navbtn btn-secondary"><<link `setup.t("hub.debts")` "Debt Ledger">><</link>></span> <</if>> </nav> </div> <<set $narrative_context to "">>
/* Passage technique / debug — non exposé dans le hub (pas de statut réputation UI). */ <<silently>> <<run setup.applyGameDataCatalog()>> <<run setup.ensureSkillsState()>> <<run setup.checkReputationLadder({ silent: true })>> <</silently>> <div class="ltn-shell rep-ladder-page"> <<print setup.renderPageHeader(setup.t("ladder.tiers"), setup.t("ladder.sub"), setup.t("ladder.progress"))>> <<print setup.renderReputationLadderHTML()>> <nav class="ltn-footer-nav"> <span class="navbtn btn-ghost"><<link `setup.t("common.back_hub")` "Hub">><</link>></span> <span class="navbtn btn-secondary"><<link `setup.t("circle.desk")` "Circle Desk">><</link>></span> </nav> </div>
<<run setup.ensureEmpireState()>> <<run setup.ensureCardArtState()>> <<run setup.ensureStaffState()>> /* Message flash une seule fois à l'arrivée */ <<if !$staff_hire_keep_msg>><<set $last_staff_hire_msg to "">><</if>> <<set $staff_hire_keep_msg to false>> <div class="ltn-shell staff-hire-page"> <<print setup.renderPageHeader(setup.t("staff.title"), setup.t("staff.sub"), setup.t("common.day"))>> <div id="staff-hire-mount" class="staff-hire-mount"> <p class="text-ink-muted"><<= setup.t("staff.loading") >></p> </div> <nav class="ltn-footer-nav"> <span class="navbtn btn-ghost"><<link `setup.t("common.back_hub")` "Hub">><</link>></span> <span class="navbtn btn-secondary"><<link `setup.t("cards.catalog")` "Card Catalog">><</link>></span> </nav> </div> <<script>> (function () { var done = false; function boot() { if (done) return; if (!document.getElementById("staff-hire-mount")) return; done = true; if (typeof setup.mountStaffHire === "function") { setup.mountStaffHire(); } } if (document.readyState === "loading") { document.addEventListener("DOMContentLoaded", boot); } else { boot(); } setTimeout(boot, 0); })(); <</script>>
<<silently>> <<run setup.applyGameDataCatalog()>> <<if !$narrative_scene_id>> <<goto "Hub">> <</if>> <<set _nsc to setup.getNarrativeScene($narrative_scene_id)>> <<if !_nsc>> <<goto "Hub">> <</if>> /* Garde favor si scène principale d'intrigue (aucune active pour l'instant) */ <<if _nsc.kind === "favor" && _nsc.charId && !setup.isFavorPassageOpen(_nsc.charId, _nsc.id)>> <<if !$debug_bypass_guards>> <<goto "Hub">> <</if>> <</if>> <<if _nsc.charId>> <<set $hub_scene_char to _nsc.charId>> <<set $favor_scene_id to _nsc.id>> <</if>> <</silently>> <div id="narr-scene-root"> <<print setup.renderNarrativeSceneHTML($narrative_scene_id)>> </div> <<script>> (function () { function boot() { if (typeof setup.bindNarrativeScene === "function") { setup.bindNarrativeScene(document); } } setTimeout(boot, 0); $(document).one(":passagedisplay", boot); })(); <</script>>
/* Compat : les intrigues terminaient sur Recovery Result */ <<goto "Recovery Result">>
<<silently>> <<run setup.applyGameDataCatalog()>> <<run setup.ensureSkillsState()>> <<set $debug_bypass_guards to true>> <</silently>> <div class="ltn-shell debug-menu-page"> <<print setup.renderPageHeader(setup.t("debug.menu"), setup.t("debug.sub"), setup.t("debug.dev"))>> <div class="debug-menu-actions ltn-actions ltn-actions--start"> <span class="navbtn btn-secondary"><<link `setup.t("debug.ctrl5")`>><<run setup.debugMaxControlAll()>><<goto "Debug Menu">><</link>></span> <span class="navbtn btn-secondary"><<link `setup.t("debug.unlock_cast")`>><<run setup.debugUnlockCast()>><<goto "Debug Menu">><</link>></span> </div> <div id="debug-scenes-mount" class="debug-scenes-mount"> <<print setup.renderDebugSceneMenuHTML()>> </div> <nav class="ltn-footer-nav"> <span class="navbtn btn-primary"><<link `setup.t("common.hub")` "Hub">><</link>></span> <span class="navbtn btn-ghost"><<link `setup.t("debug.title_screen")` "Start">><</link>></span> </nav> </div> <<script>> (function () { function boot() { if (typeof setup.bindDebugSceneMenu === "function") { setup.bindDebugSceneMenu(document); } } setTimeout(boot, 0); $(document).one(":passagedisplay", boot); })(); <</script>>