summaryrefslogtreecommitdiff
path: root/layouts/txts/single.html
diff options
context:
space:
mode:
authorSivaldo <sivaldodavi@disroot.org>2026-06-13 19:20:23 -0300
committerSivaldo <sivaldodavi@disroot.org>2026-06-13 19:20:23 -0300
commit7316238f16655bd127b04476bbf7864b27f940f9 (patch)
tree61f25290b3e5fd14894e52754cfe6dd4e85845ef /layouts/txts/single.html
Commit inicialHEADmain
Diffstat (limited to 'layouts/txts/single.html')
-rw-r--r--layouts/txts/single.html224
1 files changed, 224 insertions, 0 deletions
diff --git a/layouts/txts/single.html b/layouts/txts/single.html
new file mode 100644
index 0000000..d8f7eb1
--- /dev/null
+++ b/layouts/txts/single.html
@@ -0,0 +1,224 @@
+{{ define "title" }}{{ .Title }} · {{ .Site.Title }}{{ end }}
+
+{{ define "header" }}
+ {{ $discSlug := .RelPermalink | strings.TrimSuffix "/" | path.Dir | path.Base }}
+ <a class="site-name" href="{{ "/" | relURL }}">direito</a>
+ {{ range $.Site.Sections }}
+ {{ if and (eq .Section "txts") (eq (.RelPermalink | strings.TrimSuffix "/" | path.Base) $discSlug) }}
+ <span class="header-sep">/</span>
+ <a class="breadcrumb-link" href="{{ .RelPermalink }}">{{ .Title }}</a>
+ {{ end }}
+ {{ end }}
+ <span class="header-sep">/</span>
+ <span class="breadcrumb">{{ .Title }}</span>
+{{ end }}
+
+{{ define "main" }}
+{{ $slug := .File.BaseFileName }}
+{{ $discSlug := .RelPermalink | strings.TrimSuffix "/" | path.Dir | path.Base }}
+
+{{/* Encontra quiz do assunto (exercício, não simulado) */}}
+{{ $quizPage := false }}
+{{ range $.Site.RegularPages }}
+ {{ if eq .Section "quizzes" }}
+ {{ $parent := .File.Dir | strings.TrimSuffix "/" | path.Base }}
+ {{ if and (eq $parent $discSlug) (eq .File.BaseFileName $slug) }}
+ {{ if not (or (.Params.simulado) (in (.File.BaseFileName | lower) "simulado")) }}
+ {{ $quizPage = . }}
+ {{ end }}
+ {{ end }}
+ {{ end }}
+{{ end }}
+
+<div class="page-text fade">
+ <div class="text-meta">
+ {{ range $.Site.Sections }}
+ {{ if and (eq .Section "txts") (eq (.RelPermalink | strings.TrimSuffix "/" | path.Base) $discSlug) }}
+ <span>{{ .Title }}</span><span class="dot"></span>
+ {{ end }}
+ {{ end }}
+ <span>assunto</span>
+ </div>
+ <h1 class="text-title">{{ .Title }}</h1>
+
+ {{/* Colapsáveis: guia de estudo e materiais do assunto */}}
+ {{ $hasExtras := or .Params.guide (or .Params.files (or .Params.videos .Params.audios)) }}
+ {{ if $hasExtras }}
+ <div class="disc-extras-wrap">
+ {{ partial "disc-extras.html" . }}
+ </div>
+ {{ end }}
+
+ <nav class="toc" id="toc-nav" style="display:none;" aria-label="Sumário">
+ <div class="toc-label">sumário</div>
+ <ol id="toc-list"></ol>
+ </nav>
+
+ <article class="prose" id="prose">{{ .Content }}</article>
+
+ {{/* Notas de rodapé — renderizadas pelo Hugo automaticamente no .Content;
+ o floater (footnotes.js) intercepta os links #fn: e mostra tooltip */}}
+
+ {{/* Questões do assunto — quiz inline embutido */}}
+ {{ if $quizPage }}
+ <div class="inline-quiz-wrap" id="inline-quiz-section">
+ <div class="inline-quiz-head">
+ <span class="sq-label">exercícios deste assunto</span>
+ <a class="inline-quiz-link" href="{{ $quizPage.RelPermalink }}">modo completo →</a>
+ </div>
+ <div id="inline-quiz-body">
+ <button class="btn btn-start-quiz" id="btn-start-inline" onclick="startInlineQuiz()">
+ Iniciar exercícios
+ </button>
+ </div>
+ <div id="inline-quiz-player" style="display:none;">
+ <div class="progress-wrap" style="margin-bottom:.75rem;"><div class="progress-fill" id="iprog"></div></div>
+ <div class="q-meta" id="iq-counter"></div>
+ <div id="iq-body"></div>
+ <div class="next-row">
+ <button class="btn" id="ibtn-next" onclick="inlineNextQuestion()" style="display:none">próxima →</button>
+ </div>
+ </div>
+ <div id="inline-quiz-result" style="display:none;">
+ <div class="res-score" id="ires-pct">0%</div>
+ <div class="res-subtitle"><span id="ires-a">0</span> de <span id="ires-t">0</span> acertos</div>
+ <div class="res-msg" style="margin-top:1rem;">
+ <div class="res-msg-label">diagnóstico</div>
+ <div id="ires-msg"></div>
+ </div>
+ <div class="res-btns" style="margin-top:1.2rem;">
+ <button class="btn" onclick="restartInlineQuiz()">refazer</button>
+ <a class="btn" href="{{ $quizPage.RelPermalink }}">modo completo</a>
+ </div>
+ </div>
+ </div>
+ <script>
+ (function() {
+ const RAW = {{ $quizPage.RawContent | jsonify | safeJS }};
+ // Remove frontmatter YAML e notas de rodapé
+ const body = RAW.replace(/^---[\s\S]*?---\n/, '').replace(/\n\[\^\d+\]:[^\n]*/g, '');
+ window._IQ = { raw: body, questions: [], idx: 0, acertos: 0, erros: 0, answered: false, flipped: false };
+ })();
+
+ function startInlineQuiz() {
+ document.getElementById('btn-start-inline').style.display = 'none';
+ const qs = prepareQuizQuestions(parseQuizBody(window._IQ.raw));
+ window._IQ.questions = qs;
+ window._IQ.idx = 0; window._IQ.acertos = 0; window._IQ.erros = 0;
+ document.getElementById('inline-quiz-player').style.display = '';
+ _iqRender();
+ }
+
+ function _iqRender() {
+ const q = window._IQ.questions[window._IQ.idx];
+ if (!q) return;
+ window._IQ.answered = false; window._IQ.flipped = false;
+ const total = window._IQ.questions.length;
+ document.getElementById('iq-counter').textContent = (window._IQ.idx + 1) + ' de ' + total;
+ document.getElementById('iprog').style.width = ((window._IQ.idx + 1) / total * 100) + '%';
+ document.getElementById('ibtn-next').style.display = 'none';
+ const body = document.getElementById('iq-body');
+ if (q.type === 'mc') {
+ body.innerHTML = '<div class="mc-area fade"><p class="q-text">' + md(q.text) + '</p><div class="options">'
+ + q.options.map((o, i) => '<button class="opt" data-opt="' + esc(o) + '" data-answer="' + esc(q.answer) + '" onclick="iqSelectOpt(this)" aria-label="Opção ' + LETRAS[i] + ': ' + o + '"><span class="opt-letter">' + LETRAS[i] + '</span><span>' + md(o) + '</span></button>').join('')
+ + '</div><div class="feedback-line" id="iq-feedback" aria-live="polite"><span class="feedback-dot"></span><span id="iq-feedback-msg"></span></div>'
+ + (q.comment ? '<div class="comment-block" id="iq-comment"><div class="comment-label">comentário</div><div>' + md(q.comment) + '</div></div>' : '')
+ + '</div>';
+ } else {
+ body.innerHTML = '<div class="flashcard-area fade"><p class="q-text">' + md(q.text) + '</p>'
+ + '<div class="flashcard-simple" id="iq-flashcard"><button class="btn btn-reveal" onclick="iqFlip()">Revelar Resposta</button></div>'
+ + '<div class="feedback-line" id="iq-feedback" aria-live="polite"><span class="feedback-dot"></span><span id="iq-feedback-msg"></span></div>'
+ + (q.comment ? '<div class="comment-block" id="iq-comment"><div class="comment-label">comentário</div><div>' + md(q.comment) + '</div></div>' : '')
+ + '<div class="flashcard-btns" id="iq-fc-btns"><button class="btn btn-ok" onclick="iqMarkOk()">✓ Acertei</button><button class="btn btn-bad" onclick="iqMarkBad()">✗ Errei</button></div>'
+ + '</div>';
+ }
+ }
+
+ function iqSelectOpt(btn) {
+ if (window._IQ.answered) return;
+ window._IQ.answered = true;
+ const chosen = btn.dataset.opt, correct = btn.dataset.answer;
+ btn.closest('.options').querySelectorAll('.opt').forEach(b => {
+ b.disabled = true;
+ if (b.dataset.opt === correct) b.classList.add('correct');
+ else if (b === btn) b.classList.add('wrong');
+ else b.classList.add('revealed');
+ });
+ const ok = chosen === correct;
+ ok ? window._IQ.acertos++ : window._IQ.erros++;
+ _iqFeedback(ok, ok ? 'Correto' : 'Incorreto — a correta está destacada');
+ document.getElementById('iq-comment')?.classList.add('show');
+ document.getElementById('ibtn-next').style.display = '';
+ }
+
+ function iqFlip() {
+ const q = window._IQ.questions[window._IQ.idx];
+ const card = document.getElementById('iq-flashcard');
+ if (card) card.innerHTML = '<div class="ref-label">resposta de referência</div><div class="ref-content">' + md(q.reference) + '</div>';
+ document.getElementById('iq-fc-btns')?.style && (document.getElementById('iq-fc-btns').style.display = '');
+ }
+
+ function iqMarkOk() { _iqMark(true); }
+ function iqMarkBad() { _iqMark(false); }
+ function _iqMark(ok) {
+ if (window._IQ.answered) return;
+ window._IQ.answered = true;
+ ok ? window._IQ.acertos++ : window._IQ.erros++;
+ _iqFeedback(ok, ok ? 'Marcado como acertado' : 'Marcado como errado');
+ document.getElementById('iq-comment')?.classList.add('show');
+ const btns = document.getElementById('iq-fc-btns');
+ if (btns) btns.innerHTML = '';
+ document.getElementById('ibtn-next').style.display = '';
+ }
+
+ function _iqFeedback(ok, msg) {
+ const fb = document.getElementById('iq-feedback');
+ if (fb) { fb.className = 'feedback-line show ' + (ok ? 'ok' : 'bad'); }
+ const fm = document.getElementById('iq-feedback-msg');
+ if (fm) fm.textContent = msg;
+ }
+
+ function inlineNextQuestion() {
+ window._IQ.idx++;
+ if (window._IQ.idx >= window._IQ.questions.length) {
+ _iqShowResult();
+ } else {
+ _iqRender();
+ }
+ }
+
+ function _iqShowResult() {
+ document.getElementById('inline-quiz-player').style.display = 'none';
+ document.getElementById('inline-quiz-result').style.display = '';
+ const { acertos, erros, questions } = window._IQ;
+ const total = questions.length;
+ const pct = total ? Math.round(acertos / total * 100) : 0;
+ document.getElementById('ires-pct').textContent = pct + '%';
+ document.getElementById('ires-a').textContent = acertos;
+ document.getElementById('ires-t').textContent = total;
+ let nivel = pct >= 90 ? 'Excelente' : pct >= 70 ? 'Bom' : pct >= 50 ? 'Regular' : 'Insuficiente';
+ let det = pct >= 90 ? 'Domínio sólido deste assunto.' : pct >= 70 ? 'Boa base, revise os erros.' : pct >= 50 ? 'Lacunas importantes, releia o texto.' : 'Retome o conteúdo antes de prosseguir.';
+ document.getElementById('ires-msg').innerHTML = '<strong>' + nivel + '</strong> — ' + acertos + ' de ' + total + ' (' + pct + '%). ' + det;
+ }
+
+ function restartInlineQuiz() {
+ document.getElementById('inline-quiz-result').style.display = 'none';
+ window._IQ.idx = 0; window._IQ.acertos = 0; window._IQ.erros = 0;
+ window._IQ.questions = prepareQuizQuestions(parseQuizBody(window._IQ.raw));
+ document.getElementById('inline-quiz-player').style.display = '';
+ _iqRender();
+ }
+ </script>
+ {{ end }}
+
+ {{ if .Params.references }}
+ <div class="references">
+ <div class="ref-head">referências</div>
+ <div class="ref-list">
+ {{ range .Params.references }}<p>{{ . }}</p>{{ end }}
+ </div>
+ </div>
+ {{ end }}
+</div>
+
+{{ end }}