diff --git a/src/app/(dashboard)/dashboard/playground/components/ParamSliders.tsx b/src/app/(dashboard)/dashboard/playground/components/ParamSliders.tsx
new file mode 100644
index 0000000000..ebbd48883a
--- /dev/null
+++ b/src/app/(dashboard)/dashboard/playground/components/ParamSliders.tsx
@@ -0,0 +1,176 @@
+"use client";
+
+// src/app/(dashboard)/dashboard/playground/components/ParamSliders.tsx
+
+export interface PlaygroundParams {
+ temperature: number;
+ max_tokens: number;
+ top_p: number;
+ presence_penalty: number;
+ frequency_penalty: number;
+ seed: number | null;
+ stop: string;
+ jsonMode: boolean;
+}
+
+export const DEFAULT_PARAMS: PlaygroundParams = {
+ temperature: 1.0,
+ max_tokens: 1024,
+ top_p: 1.0,
+ presence_penalty: 0,
+ frequency_penalty: 0,
+ seed: null,
+ stop: "",
+ jsonMode: false,
+};
+
+interface ParamSlidersProps {
+ params: PlaygroundParams;
+ setParams: (params: PlaygroundParams) => void;
+}
+
+interface SliderRowProps {
+ label: string;
+ value: number;
+ min: number;
+ max: number;
+ step: number;
+ onChange: (v: number) => void;
+}
+
+function SliderRow({ label, value, min, max, step, onChange }: SliderRowProps) {
+ return (
+
+ );
+}
+
+/**
+ * Sliders for temperature, max_tokens, top_p, penalties, seed, stop, JSON mode.
+ * Props: { params, setParams }
+ */
+export default function ParamSliders({ params, setParams }: ParamSlidersProps) {
+ function update(key: K, value: PlaygroundParams[K]) {
+ setParams({ ...params, [key]: value });
+ }
+
+ return (
+
+ );
+}
diff --git a/src/app/(dashboard)/dashboard/playground/components/TokenCostCounter.tsx b/src/app/(dashboard)/dashboard/playground/components/TokenCostCounter.tsx
new file mode 100644
index 0000000000..5975cd7696
--- /dev/null
+++ b/src/app/(dashboard)/dashboard/playground/components/TokenCostCounter.tsx
@@ -0,0 +1,29 @@
+"use client";
+
+// src/app/(dashboard)/dashboard/playground/components/TokenCostCounter.tsx
+
+interface TokenCostCounterProps {
+ tokensIn: number;
+ tokensOut: number;
+ costUsd: number | null;
+}
+
+/**
+ * Displays token counts and estimated cost.
+ * D13: Cost is labeled "(estimated)" to reflect client-side calculation.
+ */
+export default function TokenCostCounter({ tokensIn, tokensOut, costUsd }: TokenCostCounterProps) {
+ if (tokensIn === 0 && tokensOut === 0 && costUsd === null) {
+ return null;
+ }
+
+ return (
+
+ {tokensIn > 0 && {tokensIn}↑}
+ {tokensOut > 0 && {tokensOut}↓}
+ {costUsd !== null && costUsd > 0 && (
+ · ${costUsd.toFixed(4)} (estimated)
+ )}
+
+ );
+}