<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>일정압력설 &#8211; MyEngNote</title>
	<atom:link href="https://myengnote.com/tag/%EC%9D%BC%EC%A0%95%EC%95%95%EB%A0%A5%EC%84%A4/feed/" rel="self" type="application/rss+xml" />
	<link>https://myengnote.com</link>
	<description></description>
	<lastBuildDate>Wed, 08 Jul 2026 06:32:51 +0000</lastBuildDate>
	<language>ko-KR</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=7.1.2</generator>
	<item>
		<title>클러치 &#038; 브레이크 계산기 &#038; 시뮬레이터</title>
		<link>https://myengnote.com/clutch-brake-torque-power-simulator/</link>
					<comments>https://myengnote.com/clutch-brake-torque-power-simulator/#respond</comments>
		
		<dc:creator><![CDATA[동동]]></dc:creator>
		<pubDate>Thu, 02 Jul 2026 23:51:17 +0000</pubDate>
				<category><![CDATA[공학계산기]]></category>
		<category><![CDATA[마찰클러치]]></category>
		<category><![CDATA[밴드브레이크]]></category>
		<category><![CDATA[일정마모설]]></category>
		<category><![CDATA[일정압력설]]></category>
		<category><![CDATA[제동토크]]></category>
		<guid isPermaLink="false">https://myengnote.com/clutch-brake-torque-power-simulator/</guid>

					<description><![CDATA[마찰 계수, 작용 하중, 접촉 반경 및 랩 각도에 따른 단판 클러치의 동력 전달(Uniform Wear/Pressure)과 밴드 브레이크의 제동 토크 및 인장비(Euler-Eytelwein)를 정밀 해석하고 마찰 맞물림/제동 거동을 2D 그래픽으로 검증하는 복합 기계요소 시뮬레이터입니다. <a href="https://myengnote.com/clutch-brake-torque-power-simulator/" style="text-decoration:none; color:#0073aa; font-weight:bold;">[본문 전체보기 >]</a>]]></description>
										<content:encoded><![CDATA[
<h2 style="font-size: 1.6em; font-weight: 800; color: #0c0e25; border-bottom: 2px solid #00f2fe; padding-bottom: 8px; margin-bottom: 20px;"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f680.png" alt="🚀" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 클러치 &#038; 브레이크 계산기 &#038; 시뮬레이터</h2>


<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&#038;family=Outfit:wght@400;500;600;700;800&#038;display=swap" rel="stylesheet">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<style>
/* Scoped & Isolated Styles for clutchbrake-calculator-wrapper */
        /* Modern Reset and Design Tokens */
        .clutchbrake-calculator-wrapper *, .clutchbrake-calculator-wrapper *::before, .clutchbrake-calculator-wrapper *::after {
            box-sizing: border-box;
            margin: 0;
            padding: 0;
        }
        .clutchbrake-calculator-wrapper {
            --color-bg-dark: #f8f9fd;
            --color-bg-deep: #ffffff;
            --color-panel-bg: rgba(255, 255, 255, 0.85);
            --color-border: rgba(0, 0, 0, 0.06);
            --color-border-hover: rgba(0, 0, 0, 0.12);
            --color-text-main: #1e293b;
            --color-text-muted: #475569;
            --color-text-dark: #94a3b8;
            --color-cyan: #0284c7;
            --color-cyan-glow: rgba(2, 132, 199, 0.15);
            --color-magenta: #db2777;
            --color-magenta-glow: rgba(219, 39, 119, 0.15);
            --color-purple: #7c3aed;
            --color-purple-glow: rgba(124, 58, 237, 0.12);
            --color-success: #10b981;
            --color-warning: #f59e0b;
            --gradient-primary: linear-gradient(135deg, var(--color-cyan) 0%, var(--color-purple) 100%);
            --gradient-accent: linear-gradient(135deg, var(--color-magenta) 0%, var(--color-purple) 100%);
            --gradient-panel: linear-gradient(180deg, rgba(255, 255, 255, 0.9) 0%, rgba(248, 250, 252, 0.95) 100%);
            --font-heading: 'Outfit', -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
            --font-body: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
            --shadow-neon-cyan: 0 0 15px var(--color-cyan-glow);
            --shadow-neon-magenta: 0 0 15px var(--color-magenta-glow);
            --shadow-card: 0 8px 32px 0 rgba(15, 23, 42, 0.05);
            --blur-glass: blur(16px);
        }
        .clutchbrake-calculator-wrapper {
            background-color: var(--color-bg-dark);
            color: var(--color-text-main);
            font-family: var(--font-body);
            min-height: 100vh;
            display: flex;
            justify-content: center;
            overflow-x: hidden;
            position: relative;
        }
        .app-background-glow {
            position: absolute;
            top: 0; left: 0; width: 100%; height: 100%;
            z-index: -1; overflow: hidden; pointer-events: none;
        }
        .app-background-glow::before, 
        .app-background-glow::after {
            content: ''; position: absolute; width: 600px; height: 600px; border-radius: 50%; filter: blur(140px); opacity: 0.12;
        }
        .app-background-glow::before { background: var(--color-cyan); top: -10%; right: -5%; animation: pulse-slow 15s infinite alternate; }
        .app-background-glow::after { background: var(--color-purple); bottom: -10%; left: -5%; animation: pulse-slow 20s infinite alternate-reverse; }
        @keyframes pulse-slow {
            0% { transform: scale(1) translate(0, 0); opacity: 0.08; }
            100% { transform: scale(1.2) translate(50px, 50px); opacity: 0.15; }
        }
        .app-container {
            width: 100%; max-width: 1440px; padding: 24px; display: flex; flex-direction: column; gap: 24px;
        }
        .app-header {
            display: flex; justify-content: space-between; align-items: center; padding: 20px 24px;
            background: var(--color-panel-bg); backdrop-filter: var(--blur-glass); border: 1px solid var(--color-border); border-radius: 16px; box-shadow: var(--shadow-card);
        }
        .logo-area { display: flex; align-items: center; gap: 16px; }
        .logo-icon {
            font-size: 32px; background: linear-gradient(135deg, var(--color-cyan), var(--color-magenta)); -webkit-background-clip: text; -webkit-text-fill-color: transparent;
            display: flex; align-items: center; justify-content: center;
        }
        .logo-area h1 {
            font-family: var(--font-heading); font-weight: 800; font-size: 24px; letter-spacing: 1.5px;
            background: linear-gradient(90deg, var(--color-text-main), var(--color-text-dark)); -webkit-background-clip: text; -webkit-text-fill-color: transparent;
        }
        .logo-area .subtitle { font-size: 12px; color: var(--color-text-muted); font-weight: 500; letter-spacing: 0.5px; }
        .header-badge {
            display: flex; align-items: center; gap: 10px; background: rgba(219, 39, 119, 0.1); border: 1px solid rgba(219, 39, 119, 0.2); padding: 6px 14px; border-radius: 20px;
        }
        .pulse-dot {
            width: 8px; height: 8px; background-color: var(--color-magenta); border-radius: 50%; box-shadow: 0 0 10px var(--color-magenta); animation: pulse-dot-anim 1.5s infinite;
        }
        @keyframes pulse-dot-anim {
            0% { transform: scale(0.9); opacity: 0.6; }
            50% { transform: scale(1.2); opacity: 1; }
            100% { transform: scale(0.9); opacity: 0.6; }
        }
        .badge-text { font-size: 11px; font-weight: 600; color: var(--color-magenta); letter-spacing: 0.5px; }
        /* Premium 2-Column Responsive Layout Setup */
        .app-main-grid { display: grid; grid-template-columns: 340px 1fr 340px; gap: 24px; align-items: start; }
        .panel {
            background: var(--gradient-panel); backdrop-filter: var(--blur-glass); border: 1px solid var(--color-border); border-radius: 20px; padding: 24px; box-shadow: var(--shadow-card);
            display: flex; flex-direction: column; gap: 18px; transition: border-color 0.3s ease, box-shadow 0.3s ease;
        }
        .panel:hover { border-color: var(--color-border-hover); }
        .panel-header { display: flex; align-items: center; gap: 12px; border-bottom: 1px solid var(--color-border); padding-bottom: 14px; }
        .panel-header i { font-size: 18px; }
        .panel-header h2 { font-family: var(--font-heading); font-size: 18px; font-weight: 600; letter-spacing: 0.5px; }
        .text-cyan { color: var(--color-cyan); }
        .text-magenta { color: var(--color-magenta); }
        .text-purple { color: var(--color-purple); }
        .control-panel { grid-column: 1; }
        .simulation-panel { grid-column: 2; }
        .results-container-panel { grid-column: 3; display: flex; flex-direction: column; gap: 24px; }
        .input-group { display: flex; flex-direction: column; gap: 8px; }
        .input-label-row { display: flex; justify-content: space-between; align-items: center; }
        .input-label-row label { font-size: 13px; font-weight: 600; color: var(--color-text-main); display: flex; align-items: center; gap: 8px; }
        .helper-text { font-size: 10px; color: var(--color-text-muted); font-weight: 500; }
        .segmented-control {
            display: grid; grid-template-columns: repeat(2, 1fr); background: rgba(0, 0, 0, 0.03); border: 1px solid var(--color-border); padding: 4px; border-radius: 12px; gap: 4px;
        }
        .segmented-btn {
            background: transparent; border: none; color: var(--color-text-muted); padding: 8px 2px; border-radius: 8px; font-size: 10.5px; font-weight: 700; cursor: pointer; transition: all 0.2s ease; text-align: center;
        }
        .segmented-btn:hover { color: var(--color-text-main); background: rgba(0, 0, 0, 0.015); }
        .segmented-btn.active { background: #ffffff; color: var(--color-cyan); box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05); }
                .number-input-wrapper {
            display: flex;
            position: relative;
            border-radius: 8px;
            overflow: hidden;
            border: 1px solid var(--color-border);
            background: #ffffff;
            transition: all 0.2s ease;
        }
        .number-input-wrapper:focus-within {
            border-color: var(--color-cyan);
            box-shadow: 0 0 10px var(--color-cyan-glow);
        }
        .number-input-wrapper:focus-within { border-color: var(--color-cyan); box-shadow: 0 0 10px var(--color-cyan-glow); }
                .custom-number-input {
            flex: 1;
            width: 0;
            min-width: 0;
            background: #f8fafc !important;
            border: none !important;
            outline: none !important;
            color: #0f172a !important;
            padding: 10px 14px !important;
            font-family: var(--font-body) !important;
            font-size: 15px !important;
            font-weight: 700 !important;
            text-align: right !important;
            box-shadow: none !important;
            -webkit-appearance: none !important;
            -moz-appearance: textfield !important;
        }
        .custom-number-input::-webkit-outer-spin-button,
        .custom-number-input::-webkit-inner-spin-button {
            -webkit-appearance: none;
            margin: 0;
        }
        .custom-number-input::-webkit-outer-spin-button, .custom-number-input::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
                .unit-badge {
            background: rgba(0, 0, 0, 0.03);
            color: var(--color-text-muted);
            font-size: 11px;
            font-weight: 700;
            padding: 0 14px;
            display: flex;
            align-items: center;
            justify-content: center;
            border-left: 1px solid var(--color-border);
            pointer-events: none;
            flex-shrink: 0;
        }
        .custom-slider {
            -webkit-appearance: none; width: 100%; height: 6px; border-radius: 3px; background: rgba(0, 0, 0, 0.05); outline: none; margin: 4px 0; transition: background 0.2s ease;
        }
        .custom-slider::-webkit-slider-thumb {
            -webkit-appearance: none; appearance: none; width: 18px; height: 18px; border-radius: 50%; cursor: pointer; transition: transform 0.1s ease, box-shadow 0.2s ease;
        }
        .slider-cyan::-webkit-slider-thumb { background: var(--color-cyan); box-shadow: 0 0 8px var(--color-cyan); }
        .slider-cyan::-webkit-slider-thumb:hover { transform: scale(1.2); }
        .slider-magenta::-webkit-slider-thumb { background: var(--color-magenta); box-shadow: 0 0 8px var(--color-magenta); }
        .slider-magenta::-webkit-slider-thumb:hover { transform: scale(1.2); }
        .slider-purple::-webkit-slider-thumb { background: var(--color-purple); box-shadow: 0 0 8px var(--color-purple); }
        .slider-purple::-webkit-slider-thumb:hover { transform: scale(1.2); }
        .slider-cyan::-moz-range-thumb { width: 18px; height: 18px; border: none; border-radius: 50%; background: var(--color-cyan); }
        .slider-magenta::-moz-range-thumb { width: 18px; height: 18px; border: none; border-radius: 50%; background: var(--color-magenta); }
        .slider-purple::-moz-range-thumb { width: 18px; height: 18px; border: none; border-radius: 50%; background: var(--color-purple); }
        .presets-section { display: flex; flex-direction: column; gap: 10px; border-top: 1px solid var(--color-border); padding-top: 16px; }
        .presets-section h3 { font-size: 13px; font-weight: 700; color: var(--color-text-main); display: flex; align-items: center; gap: 8px; }
        .presets-grid { display: flex; flex-direction: column; gap: 8px; }
        .preset-btn {
            background: rgba(0, 0, 0, 0.015); border: 1px solid var(--color-border); border-radius: 10px; padding: 8px 12px; cursor: pointer; color: var(--color-text-main);
            display: flex; align-items: center; gap: 12px; text-align: left; transition: all 0.2s ease;
        }
        .preset-btn:hover { background: rgba(0, 0, 0, 0.04); transform: translateX(4px); }
        .preset-btn.active {
            background: linear-gradient(90deg, var(--color-cyan-glow), var(--color-magenta-glow)); border-color: var(--color-cyan); box-shadow: 0 0 10px var(--color-cyan-glow);
        }
        .preset-icon {
            width: 28px; height: 28px; background: rgba(0, 0, 0, 0.02); border-radius: 8px; display: flex; align-items: center; justify-content: center; font-size: 12px; color: var(--color-cyan);
        }
        .preset-btn:hover .preset-icon, .preset-btn.active .preset-icon { background: var(--gradient-primary); color: #fff; }
        .preset-name { font-size: 11.5px; font-weight: 600; }
        .simulation-panel { width: 100%; justify-content: space-between; }
        /* Restored: Max-width constraint completely REMOVED for majestic wide screen experience! */
        .canvas-wrapper {
            position: relative; 
            width: 100%; 
            background: radial-gradient(circle at center, #ffffff 0%, #f1f5f9 100%); 
            border: 1px solid rgba(0, 0, 0, 0.06); 
            border-radius: 16px;
            overflow: hidden; 
            display: flex; 
            align-items: center; 
            justify-content: center; 
            box-shadow: 0 4px 20px rgba(15, 23, 42, 0.04);
        }
        #physics-canvas { display: block; width: 100%; height: auto; aspect-ratio: 16 / 10; }
        /* Fixed Overlay UI CSS styles to prevent overlapping */
        .canvas-overlay-data {
            position: absolute;
            top: 20px;
            left: 20px;
            z-index: 10;
            pointer-events: none;
        }
        .overlay-item {
            background: rgba(255, 255, 255, 0.85);
            backdrop-filter: blur(8px);
            -webkit-backdrop-filter: blur(8px);
            border: 1px solid rgba(255, 255, 255, 0.6);
            padding: 8px 16px;
            border-radius: 12px;
            box-shadow: 0 4px 20px rgba(15, 23, 42, 0.08);
            display: flex;
            align-items: center;
            gap: 10px;
        }
        .overlay-item .label {
            font-size: 11px;
            font-weight: 700;
            color: var(--color-text-muted);
            text-transform: uppercase;
            letter-spacing: 0.5px;
        }
        .overlay-item .value {
            font-size: 13px;
            font-weight: 800;
            color: var(--color-magenta);
            transition: color 0.3s ease;
        }
        .action-overlay-area {
            position: absolute; bottom: 20px; right: 20px; z-index: 10;
        }
        .action-btn {
            background: var(--gradient-accent); border: none; color: #fff; padding: 11px 20px; border-radius: 12px; font-size: 12.5px; font-weight: 700;
            cursor: pointer; display: flex; align-items: center; gap: 8px; box-shadow: 0 4px 15px var(--color-magenta-glow); transition: all 0.25s ease;
        }
        .action-btn:hover { transform: translateY(-2px); box-shadow: 0 6px 20px var(--color-magenta); }
        .action-btn:active { transform: translateY(1px); }
        /* Restored: metrics strip width is 100% wide matching restored canvas wrapper */
        .simulation-metrics-strip {
            display: flex; 
            background: rgba(0, 0, 0, 0.015); 
            border: 1px solid var(--color-border); 
            border-radius: 12px; 
            padding: 14px 20px;
            justify-content: space-around; 
            align-items: center; 
            gap: 10px; 
            margin: 12px auto 0 auto;
            width: 100%;
        }
        .mini-metric { display: flex; flex-direction: column; align-items: center; gap: 4px; text-align: center; }
        .mini-metric .label { font-size: 10px; font-weight: 600; color: var(--color-text-muted); text-transform: uppercase; letter-spacing: 0.5px; }
        .mini-metric .value { font-size: 14px; font-weight: 700; color: var(--color-text-main); font-family: var(--font-heading); }
        .mini-divider { width: 1px; height: 24px; background: var(--color-border); }
        .results-panel { display: flex; flex-direction: column; gap: 18px; }
        .ratio-readout-box {
            background: linear-gradient(135deg, var(--color-cyan-glow) 0%, var(--color-purple-glow) 100%); border: 1px solid rgba(2, 132, 199, 0.15); border-radius: 16px;
            padding: 24px; text-align: center; display: flex; flex-direction: column; align-items: center; gap: 8px; box-shadow: 0 4px 20px rgba(0, 0, 0, 0.02);
        }
        .ratio-title { font-size: 11px; font-weight: 700; color: var(--color-cyan); letter-spacing: 1px; text-transform: uppercase; }
        .ratio-value {
            font-family: var(--font-heading); font-weight: 800; font-size: 28px; background: linear-gradient(90deg, var(--color-text-main), var(--color-cyan));
            -webkit-background-clip: text; -webkit-text-fill-color: transparent;
        }
        .ratio-type { font-size: 11px; font-weight: 600; color: var(--color-text-muted); }
        .results-grid { display: flex; flex-direction: column; gap: 12px; }
        .result-card {
            background: rgba(255, 255, 255, 0.85); box-shadow: 0 2px 8px rgba(0, 0, 0, 0.03); border: 1px solid var(--color-border); border-radius: 12px;
            padding: 14px 18px; display: flex; align-items: center; gap: 16px; transition: all 0.2s ease;
        }
        .result-card:hover { transform: translateY(-2px); border-color: var(--color-cyan); background: var(--color-cyan-glow); }
        .card-icon {
            width: 38px; height: 38px; background: rgba(0, 0, 0, 0.015); border: 1px solid var(--color-border); border-radius: 10px;
            display: flex; align-items: center; justify-content: center; font-size: 14px; color: var(--color-text-muted);
        }
        .result-card:hover .card-icon { color: var(--color-cyan); border-color: var(--color-cyan); background: var(--color-cyan-glow); }
        .card-content { display: flex; flex-direction: column; gap: 2px; }
        .card-unit { font-size: 11px; font-weight: 600; color: var(--color-text-muted); }
        .card-value { font-family: var(--font-heading); font-weight: 700; font-size: 17px; color: var(--color-text-main); }
        .formula-card {
            background: #ffffff; border: 1px solid var(--color-border); border-radius: 16px; padding: 20px; display: flex; flex-direction: column; gap: 10px; font-size: 12px;
            justify-content: center;
        }
        .formula-card h4 { font-weight: 700; color: var(--color-text-main); font-size: 13.5px; display: flex; align-items: center; gap: 8px; }
        .formula-equation {
            font-family: 'Outfit', 'Cambria Math', 'Times New Roman', monospace; color: #0284c7; font-size: 14px; background: #f8fafc; border: 1px solid var(--color-border);
            padding: 10px 14px; border-radius: 8px; font-weight: 600; letter-spacing: 0.5px;
        }
        @container clutch-container (max-width: 1100px) {
            .app-main-grid {
                grid-template-columns: 1fr 1fr;
                gap: 20px;
            }
            .control-panel {
                grid-column: 1;
            }
            .simulation-panel {
                grid-column: 2;
            }
            .results-container-panel {
                grid-column: 1 / span 2;
                display: grid;
                grid-template-columns: 1fr 1.2fr;
                gap: 20px;
            }
        }
        @container clutch-container (max-width: 768px) {
            .app-main-grid {
                grid-template-columns: 1fr;
            }
            .control-panel, .simulation-panel, .results-container-panel {
                grid-column: 1;
            }
            .results-container-panel {
                grid-template-columns: 1fr;
                gap: 20px;
            }
            .app-header {
                flex-direction: column;
                gap: 16px;
                text-align: center;
            }
            .logo-area {
                flex-direction: column;
                gap: 8px;
            }
        }
        @container clutch-container (max-width: 480px) {
            .app-container {
                padding: 12px;
                gap: 16px;
            }
            .panel {
                padding: 16px;
            }
            .simulation-metrics-strip {
                flex-direction: column;
                gap: 12px;
            }
            .mini-divider {
                width: 80%;
                height: 1px;
            }
        }
        .preset-details {
            display: flex;
            flex-direction: column;
            gap: 2px;
            align-items: flex-start;
            text-align: left;
        }
        .preset-spec {
            font-size: 11px;
            color: var(--color-text-muted);
            font-weight: 500;
        }
        .preset-name {
            font-size: 13px !important;
        }
/* ━━ WordPress 레이아웃 Override: 디자인 1 (2열 컴팩트 대칭 레이아웃) ━━ */
.clutchbrake-calculator-wrapper .app-main-grid,
.clutchbrake-calculator-wrapper .main-grid,
.clutchbrake-calculator-wrapper .sim-grid {
    display: grid !important;
    grid-template-columns: 340px 1fr !important;
    gap: 24px !important;
    align-items: start !important;
}
/* 3열 레이아웃을 2열 레이아웃으로 변경하는 특화 스타일 */
.clutchbrake-calculator-wrapper .right-column {
    display: flex !important;
    flex-direction: column !important;
    gap: 24px !important;
    min-width: 0 !important;
    grid-column: 2 !important;
}
.clutchbrake-calculator-wrapper .simulation-panel,
.clutchbrake-calculator-wrapper .canvas-panel,
.clutchbrake-calculator-wrapper .sim-panel {
    grid-column: auto !important;
    order: 1 !important;
    align-self: stretch !important;
}
.clutchbrake-calculator-wrapper .control-panel {
    grid-column: 1 !important;
}
/* 2열 통합 결과 분석 영역 레이아웃 */
.clutchbrake-calculator-wrapper .simulation-results-section {
    display: grid !important;
    grid-template-columns: 1.1fr 1.3fr !important;
    gap: 20px !important;
    border-top: 1px solid var(--color-border) !important;
    padding-top: 20px !important;
    margin-top: 10px !important;
    align-items: stretch !important;
}
/* Readout Box 스타일 */
.clutchbrake-calculator-wrapper .simulation-results-section .ratio-readout-box,
.clutchbrake-calculator-wrapper .simulation-results-section .re-readout-box,
.clutchbrake-calculator-wrapper .simulation-results-section .status-readout-box,
.clutchbrake-calculator-wrapper .simulation-results-section .flow-readout-box,
.clutchbrake-calculator-wrapper .simulation-results-section [class*="readout-box"],
.clutchbrake-calculator-wrapper .simulation-results-section .gauge-container {
    grid-column: 1 !important;
    grid-row: 1 !important;
    margin: 0 !important;
    height: auto !important;
    display: flex !important;
    flex-direction: column !important;
    justify-content: center !important;
}
.clutchbrake-calculator-wrapper .simulation-results-section .results-grid {
    grid-column: 2 !important;
    grid-row: 1 / span 2 !important;
    display: flex !important;
    flex-direction: column !important;
    gap: 12px !important;
    justify-content: flex-start !important;
}
.clutchbrake-calculator-wrapper .simulation-results-section .results-grid .result-card {
    flex: none !important;
    display: flex !important;
    align-items: center !important;
    min-height: 72px !important;
    height: auto !important;
    padding: 12px 16px !important;
}
.clutchbrake-calculator-wrapper .simulation-results-section .formula-card {
    grid-column: 1 !important;
    grid-row: 2 !important;
}
/* 모바일/반응형 (800px 이하) ── 항상 세로형(1열) 정렬 및 시뮬레이터 캔버스 최상단 배치 */
@media (max-width: 800px) {
    .clutchbrake-calculator-wrapper .app-main-grid,
    .clutchbrake-calculator-wrapper .main-grid,
    .clutchbrake-calculator-wrapper .sim-grid {
        grid-template-columns: 1fr !important;
        display: flex !important;
        flex-direction: column !important;
    }
    .clutchbrake-calculator-wrapper .control-panel {
        order: 2 !important;
        width: 100% !important;
    }
    .clutchbrake-calculator-wrapper .right-column {
        order: 1 !important;
        width: 100% !important;
        display: flex !important;
        flex-direction: column !important;
    }
    .clutchbrake-calculator-wrapper .simulation-panel,
    .clutchbrake-calculator-wrapper .canvas-panel,
    .clutchbrake-calculator-wrapper .sim-panel,
    .clutchbrake-calculator-wrapper .canvas-section {
        order: -1 !important;
    }
    .clutchbrake-calculator-wrapper .simulation-results-section {
        grid-template-columns: 1fr !important;
    }
    .clutchbrake-calculator-wrapper .simulation-results-section .ratio-readout-box,
    .clutchbrake-calculator-wrapper .simulation-results-section .re-readout-box,
    .clutchbrake-calculator-wrapper .simulation-results-section .status-readout-box,
    .clutchbrake-calculator-wrapper .simulation-results-section .flow-readout-box,
    .clutchbrake-calculator-wrapper .simulation-results-section [class*="readout-box"],
    .clutchbrake-calculator-wrapper .simulation-results-section .gauge-container {
        grid-column: 1 !important;
        grid-row: auto !important;
        height: auto !important;
    }
    .clutchbrake-calculator-wrapper .simulation-results-section .results-grid {
        grid-column: 1 !important;
        grid-row: auto !important;
    }
    .clutchbrake-calculator-wrapper .simulation-results-section .formula-card {
        grid-column: 1 !important;
        grid-row: auto !important;
    }
}
.clutchbrake-calculator-wrapper .app-container,
.clutchbrake-calculator-wrapper .main-container {
    max-width: 100% !important;
    padding: 12px !important;
}
/* Premium Advice/Formula Card & Typography Overrides */
.clutchbrake-calculator-wrapper .simulation-results-section .formula-card,
.clutchbrake-calculator-wrapper .results-panel .formula-card {
    background: #ffffff !important;
    border: 1px solid var(--color-border) !important;
    border-radius: 12px !important;
    padding: 16px !important;
    box-shadow: var(--shadow-card) !important;
    transition: all 0.2s ease !important;
    display: flex !important;
    flex-direction: column !important;
    justify-content: center !important;
    gap: 8px !important;
}
.clutchbrake-calculator-wrapper .simulation-results-section .formula-card h4,
.clutchbrake-calculator-wrapper .results-panel .formula-card h4 {
    font-size: 14px !important;
    font-weight: 700 !important;
    color: var(--color-text-main) !important;
    margin-top: 0 !important;
    margin-bottom: 4px !important;
    word-break: keep-all !important;
    line-height: 1.4 !important;
    display: flex !important;
    align-items: center !important;
    gap: 8px !important;
}
.clutchbrake-calculator-wrapper .formula-equation {
    font-family: 'Outfit', 'Cambria Math', 'Times New Roman', monospace !important;
    white-space: nowrap !important;
    overflow-x: auto !important;
    word-break: keep-all !important;
    text-align: center !important;
}
.clutchbrake-calculator-wrapper #text-judgment {
    font-size: 12px !important;
    font-weight: 500 !important;
    color: var(--color-text-muted) !important;
    line-height: 1.6 !important;
    word-break: keep-all !important;
}
</style>
<div class="clutchbrake-calculator-wrapper" style="position: relative; width: 100%; box-sizing: border-box; overflow: hidden; margin: 30px auto; border-radius: 20px;">
    <div class="app-background-glow" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; z-index: 1; pointer-events: none; overflow: hidden;"></div>
    <div style="position: relative; z-index: 2; width: 100%;">
    <div class="app-container">
        <!-- Header -->
        <header class="app-header">
            <div class="logo-area">
                <div class="logo-icon"><i class="fa-solid fa-compact-disc"></i></div>
                <div>
                    <h1>CLUTCH &#038; BRAKE</h1>
                    <div class="subtitle">클러치/브레이크 동력 전달 및 제동 토크 시뮬레이터</div>
                </div>
            </div>
            <div class="header-badge">
                <div class="pulse-dot"></div>
                <div class="badge-text">FRICTION ANALYSIS ACTIVE</div>
            </div>
        </header>
        <!-- Main Layout Grid -->
        <main class="app-main-grid">
            <!-- Left Panel: Controls -->
            <section class="panel control-panel">
                <div class="panel-header">
                    <i class="fa-solid fa-sliders text-cyan"></i>
                    <h2>구동 및 설계 변수</h2>
                </div>
                <!-- Core Mode selection -->
                <div class="input-group">
                    <span class="helper-text" style="font-weight:700; color:var(--color-text-muted);">해석 대상 기계요소</span>
                    <div class="segmented-control" id="control-analysis-mode">
                        <button class="segmented-btn active" id="btn-mode-clutch">마찰 클러치</button>
                        <button class="segmented-btn" id="btn-mode-brake">밴드 브레이크</button>
                    </div>
                </div>
                <!-- Friction Coefficient mu -->
                <div class="input-group">
                    <div class="input-label-row">
                        <label for="input-mu"><i class="fa-solid fa-oil-can text-cyan"></i> 마찰 계수 (&mu;)</label>
                        <span class="helper-text">(0.10 ~ 0.60)</span>
                    </div>
                    <div class="number-input-wrapper">
                        <input type="number" id="input-mu" class="custom-number-input" min="0.1" max="0.6" value="0.35" step="any">
                        <div class="unit-badge">&mu;</div>
                    </div>
                    <input type="range" id="slider-mu" class="custom-slider slider-cyan" min="10" max="60" value="35">
                </div>
                <!-- Operating Force F -->
                <div class="input-group">
                    <div class="input-label-row">
                        <label for="input-force"><i class="fa-solid fa-weight-hanging text-magenta"></i> 인가 조작력 (F)</label>
                        <span class="helper-text">(100 ~ 5000 N)</span>
                    </div>
                    <div class="number-input-wrapper">
                        <input type="number" id="input-force" class="custom-number-input" min="100" max="5000" value="1200" step="any">
                        <div class="unit-badge">N</div>
                    </div>
                    <input type="range" id="slider-force" class="custom-slider slider-magenta" min="100" max="5000" value="1200">
                </div>
                <!-- Speed RPM N -->
                <div class="input-group">
                    <div class="input-label-row">
                        <label for="input-rpm"><i class="fa-solid fa-arrows-spin text-purple"></i> 구동축 회전 속도 (N)</label>
                        <span class="helper-text">(500 ~ 4000 RPM)</span>
                    </div>
                    <div class="number-input-wrapper">
                        <input type="number" id="input-rpm" class="custom-number-input" min="500" max="4000" value="1800" step="any">
                        <div class="unit-badge">RPM</div>
                    </div>
                    <input type="range" id="slider-rpm" class="custom-slider slider-purple" min="500" max="4000" value="1800">
                </div>
                <!-- CLUTCH SPECIFIC INPUTS -->
                <div id="clutch-inputs-container" style="display:flex; flex-direction:column; gap:16px;">
                    <div class="input-group">
                        <div class="input-label-row">
                            <label for="input-ro"><i class="fa-solid fa-circle text-cyan"></i> 마찰면 외경 (Ro)</label>
                            <span class="helper-text">(50 ~ 300 mm)</span>
                        </div>
                        <div class="number-input-wrapper">
                            <input type="number" id="input-ro" class="custom-number-input" min="50" max="300" value="180" step="any">
                            <div class="unit-badge">mm</div>
                        </div>
                        <input type="range" id="slider-ro" class="custom-slider slider-cyan" min="50" max="300" value="180">
                    </div>
                    <div class="input-group">
                        <div class="input-label-row">
                            <label for="input-ri"><i class="fa-solid fa-circle-notch text-cyan"></i> 마찰면 내경 (Ri)</label>
                            <span class="helper-text">(20 ~ 250 mm)</span>
                        </div>
                        <div class="number-input-wrapper">
                            <input type="number" id="input-ri" class="custom-number-input" min="20" max="250" value="100" step="any">
                            <div class="unit-badge">mm</div>
                        </div>
                        <input type="range" id="slider-ri" class="custom-slider slider-cyan" min="20" max="250" value="100">
                    </div>
                    <div class="input-group">
                        <span class="helper-text" style="font-weight:700; color:var(--color-text-muted);">면압 분포 설계식</span>
                        <div class="segmented-control" id="control-clutch-theory">
                            <button class="segmented-btn active" id="btn-theory-wear">일등 마모설</button>
                            <button class="segmented-btn" id="btn-theory-pressure">일등 압력설</button>
                        </div>
                    </div>
                </div>
                <!-- BRAKE SPECIFIC INPUTS (hidden initially) -->
                <div id="brake-inputs-container" style="display:none; flex-direction:column; gap:16px;">
                    <div class="input-group">
                        <div class="input-label-row">
                            <label for="input-drum-r"><i class="fa-solid fa-circle text-magenta"></i> 브레이크 드럼 반경 (R)</label>
                            <span class="helper-text">(50 ~ 300 mm)</span>
                        </div>
                        <div class="number-input-wrapper">
                            <input type="number" id="input-drum-r" class="custom-number-input" min="50" max="300" value="150" step="any">
                            <div class="unit-badge">mm</div>
                        </div>
                        <input type="range" id="slider-drum-r" class="custom-slider slider-magenta" min="50" max="300" value="150">
                    </div>
                    <div class="input-group">
                        <div class="input-label-row">
                            <label for="input-wrap"><i class="fa-solid fa-ring text-purple"></i> 밴드 감김 랩각 (&theta;)</label>
                            <span class="helper-text">(90° ~ 300°)</span>
                        </div>
                        <div class="number-input-wrapper">
                            <input type="number" id="input-wrap" class="custom-number-input" min="90" max="300" value="210" step="any">
                            <div class="unit-badge">deg</div>
                        </div>
                        <input type="range" id="slider-wrap" class="custom-slider slider-purple" min="90" max="300" value="210">
                    </div>
                </div>
                <!-- Presets -->
                <div class="presets-section">
                    <h3><i class="fa-solid fa-tags text-cyan"></i> 파워팩 사양 프리셋</h3>
                    <div class="presets-grid">
                        <button class="preset-btn active" id="preset-car-clutch">
                            <div class="preset-icon"><i class="fa-solid fa-car"></i></div>
                            <div class="preset-details"><span class="preset-name">일반 승용차 건식 클러치</span><span class="preset-spec">M/T 디스크</span></div>
                        </button>
                        <button class="preset-btn" id="preset-crane-brake">
                            <div class="preset-icon"><i class="fa-solid fa-truck-pickup"></i></div>
                            <div class="preset-details"><span class="preset-name">기중기 비상 밴드 브레이크</span><span class="preset-spec">고랩각 제동</span></div>
                        </button>
                    </div>
                </div>
            </section>
            <!-- Auto Injected Right Column wrapper for Design 1 -->
            <div class="right-column">
                <section class="panel simulation-panel">
                                <div class="panel-header">
                                    <i class="fa-solid fa-dharmachakra text-magenta"></i>
                                    <h2>체결 및 제동 물리 회전 거동 가시화 (3D Isometric)</h2>
                                </div>
                                <div class="canvas-wrapper">
                                    <canvas id="physics-canvas" width="800" height="500"></canvas>
                                    <div class="canvas-overlay-data">
                                        <div class="overlay-item">
                                            <span class="label">작동 상태:</span>
                                            <span class="value" id="overlay-run-status">동력 전달 대기중 (클러치 분리)</span>
                                        </div>
                                    </div>
                                    <div class="action-overlay-area">
                                        <button class="action-btn" id="btn-engage-action">
                                            <i class="fa-solid fa-circle-play" id="icon-action-btn"></i>
                                            <span id="txt-action-btn">클러치 체결하기 (Engage)</span>
                                        </button>
                                    </div>
                                </div>
                                <div class="simulation-metrics-strip">
                                    <div class="mini-metric">
                                        <span class="label" id="lbl-metric-1">구동축 입력 속도</span>
                                        <span class="value" id="val-speed-in">1800 RPM</span>
                                    </div>
                                    <div class="mini-divider"></div>
                                    <div class="mini-metric">
                                        <span class="label" id="lbl-metric-2">종동축 출력 속도</span>
                                        <span class="value" id="val-speed-out">0 RPM</span>
                                    </div>
                                    <div class="mini-divider"></div>
                                    <div class="mini-metric">
                                        <span class="label" id="lbl-metric-3">클러치 슬립 비율</span>
                                        <span class="value" id="val-slip">100.0%</span>
                                    </div>
                                </div>
                            <div class="simulation-results-section">
                                <div class="ratio-readout-box">
                                        <div class="ratio-title" id="txt-readout-title">전달 가능한 마찰 토크 (T)</div>
                                        <div class="ratio-value" id="txt-readout-val">58.8 N·m</div>
                                        <div class="ratio-type" id="txt-readout-sub">동력 전달 용량: 14.8 HP (11.1 kW)</div>
                                    </div>
                                <div class="results-grid">
                                        <div class="result-card">
                                            <div class="card-icon"><i class="fa-solid fa-circle-nodes"></i></div>
                                            <div class="card-content">
                                                <span class="card-unit" id="lbl-card-1">평균 마찰 접촉 반경</span>
                                                <span class="card-value" id="res-metric-1">140 mm</span>
                                            </div>
                                        </div>
                                        <div class="result-card">
                                            <div class="card-icon"><i class="fa-solid fa-bolt"></i></div>
                                            <div class="card-content">
                                                <span class="card-unit" id="lbl-card-2">구동 전력 전달 용량</span>
                                                <span class="card-value" id="res-metric-2">11.08 kW</span>
                                            </div>
                                        </div>
                                        <div class="result-card">
                                            <div class="card-icon"><i class="fa-solid fa-circle-exclamation"></i></div>
                                            <div class="card-content">
                                                <span class="card-unit" id="lbl-card-3">미끄럼 열손실 평가</span>
                                                <span class="card-value" id="res-metric-3">안전 (적정 점착 성질)</span>
                                            </div>
                                        </div>
                                    </div>
                                <section class="panel formula-card">
                                    <div class="panel-header">
                                        <i class="fa-solid fa-circle-info text-cyan"></i>
                                        <h2>설계 역학 주요 방정식</h2>
                                    </div>
                                    <div class="input-group">
                                        <span class="helper-text">토크 유도 설계식</span>
                                        <div class="formula-equation" id="lbl-formula-1">
                                            T = &mu; &times; F &times; R_mean
                                        </div>
                                    </div>
                                    <div class="input-group">
                                        <span class="helper-text">전동/제동 출력식</span>
                                        <div class="formula-equation" id="lbl-formula-2">
                                            P = T &times; &omega; &nbsp;[W]
                                        </div>
                                    </div>
                                </section>
                            </div>
                </section>
            </div>
        </main>
        <!-- Disclaimer Footer -->
        <footer class="app-disclaimer" style="margin-top: 20px; padding: 12px 16px; background: rgba(0, 0, 0, 0.015); border: 1px solid var(--color-border); border-radius: 12px; font-size: 11px; color: var(--color-text-muted); line-height: 1.5; text-align: left; display: flex; gap: 10px; align-items: flex-start; clear: both;">
            <i class="fa-solid fa-circle-info" style="color: var(--color-cyan); font-size: 14px; margin-top: 2px; flex-shrink: 0;"></i>
            <span><strong>면책 조항 (Disclaimer):</strong> 본 시뮬레이터의 계산 결과는 교육 및 참고용으로만 제공되며, 실제 제품 설계나 제작 시에는 반드시 최신 공학 규격 및 공식 표준 설계 기준을 재확인하시기 바랍니다. 계산 값의 무결성을 보장하지 않으며, 이로 인해 발생하는 직접적/간접적 손해에 대해 제작자 및 본 블로그는 어떠한 책임을 지지 않습니다.</span>
        </footer>
</div>
    <!-- CORE INTERACTIVE ENGINE -->
    </div>
</div>
<script>
        (function() {
            if (window.__clutchbrake_initialized) return;
            window.__clutchbrake_initialized = true;
            const btnModeClutch = document.getElementById('btn-mode-clutch');
            const btnModeBrake = document.getElementById('btn-mode-brake');
            const clutchInputs = document.getElementById('clutch-inputs-container');
            const brakeInputs = document.getElementById('brake-inputs-container');
            const inputMu = document.getElementById('input-mu');
            const sliderMu = document.getElementById('slider-mu');
            const inputForce = document.getElementById('input-force');
            const sliderForce = document.getElementById('slider-force');
            const inputRpm = document.getElementById('input-rpm');
            const sliderRpm = document.getElementById('slider-rpm');
            // Clutch inputs
            const inputRo = document.getElementById('input-ro');
            const sliderRo = document.getElementById('slider-ro');
            const inputRi = document.getElementById('input-ri');
            const sliderRi = document.getElementById('slider-ri');
            const btnTheoryWear = document.getElementById('btn-theory-wear');
            const btnTheoryPressure = document.getElementById('btn-theory-pressure');
            // Brake inputs
            const inputDrumR = document.getElementById('input-drum-r');
            const sliderDrumR = document.getElementById('slider-drum-r');
            const inputWrap = document.getElementById('input-wrap');
            const sliderWrap = document.getElementById('slider-wrap');
            const txtReadoutTitle = document.getElementById('txt-readout-title');
            const txtReadoutVal = document.getElementById('txt-readout-val');
            const txtReadoutSub = document.getElementById('txt-readout-sub');
            const lblMetric1 = document.getElementById('lbl-metric-1');
            const lblMetric2 = document.getElementById('lbl-metric-2');
            const lblMetric3 = document.getElementById('lbl-metric-3');
            const valSpeedIn = document.getElementById('val-speed-in');
            const valSpeedOut = document.getElementById('val-speed-out');
            const valSlip = document.getElementById('val-slip');
            const lblCard1 = document.getElementById('lbl-card-1');
            const lblCard2 = document.getElementById('lbl-card-2');
            const lblCard3 = document.getElementById('lbl-card-3');
            const resMetric1 = document.getElementById('res-metric-1');
            const resMetric2 = document.getElementById('res-metric-2');
            const resMetric3 = document.getElementById('res-metric-3');
            const lblFormula1 = document.getElementById('lbl-formula-1');
            const lblFormula2 = document.getElementById('lbl-formula-2');
            const btnEngageAction = document.getElementById('btn-engage-action');
            const iconActionBtn = document.getElementById('icon-action-btn');
            const txtActionBtn = document.getElementById('txt-action-btn');
            const overlayRunStatus = document.getElementById('overlay-run-status');
            // Internal Interactive State Model
            const state = {
                mode: 'clutch', // 'clutch' or 'brake'
                mu: 0.35,
                force: 1200.0, // N
                rpm: 1800.0,
                // Clutch
                ro: 180.0, // mm
                ri: 100.0, // mm
                theory: 'wear', // 'wear' or 'pressure'
                // Brake
                drumR: 150.0, // mm
                wrapAngle: 210.0, // deg
                // Dynamic simulation running flags
                engaged: false, // Unified Toggle Control (Clutch: clamped vs split, Brake: braking vs free)
                speedIn: 1800.0,
                speedOut: 0.0, // Output shaft for clutch, drum for brake
                slipRatio: 1.0,
                // Animation physics
                rotationAngleIn: 0.0,
                rotationAngleOut: 0.0,
                clampGap: 55.0, // horizontal distance visualizer for clutch plates (55px when split, 0px when clamped)
                leverAngle: 0.0, // angular offset visualizer for brake band lever (0 deg when free, 12 deg when pulling)
                sparks: []
            };
            const ranges = {
                mu: { min: 0.10, max: 0.60 },
                force: { min: 100.0, max: 5000.0 },
                rpm: { min: 500.0, max: 4000.0 },
                ro: { min: 50.0, max: 300.0 },
                ri: { min: 20.0, max: 250.0 },
                drumR: { min: 50.0, max: 300.0 },
                wrapAngle: { min: 90.0, max: 300.0 }
            };
            function calculateClutchBrake() {
                if (state.mode === 'clutch') {
                    // Keep ri always less than ro
                    if (state.ri >= state.ro - 10.0) {
                        state.ri = state.ro - 15.0;
                        if (state.ri < 20.0) { state.ri = 20.0; }
                        inputRi.value = state.ri.toFixed(0);
                        sliderRi.value = Math.round(state.ri);
                    }
                    const r2 = state.ro / 1000.0; // m
                    const r1 = state.ri / 1000.0; // m
                    let rMean = 0;
                    if (state.theory === 'wear') {
                        rMean = (r1 + r2) / 2.0;
                    } else {
                        rMean = (2.0 / 3.0) * (Math.pow(r2, 3) - Math.pow(r1, 3)) / (Math.pow(r2, 2) - Math.pow(r1, 2));
                    }
                    // Torque T = mu * F * R_mean
                    const torque = state.mu * state.force * rMean;
                    state.calculatedTorque = torque;
                    // Power P = T * omega / 1000 (kW)
                    const omega = (2.0 * Math.PI * state.rpm) / 60.0;
                    const power = (torque * omega) / 1000.0;
                    state.calculatedPower = power;
                    const hp = power * 1.341;
                    state.calculatedHP = hp;
                    state.rMean = rMean;
                } else {
                    // Band Brake calculation
                    const r = state.drumR / 1000.0; // m
                    const alpha = (state.wrapAngle * Math.PI) / 180.0; // rad
                    // Euler belt formula: F1 = F2 * e^(mu * alpha)
                    // F2 (slack side) = F applied
                    const F2 = state.force;
                    const F1 = F2 * Math.exp(state.mu * alpha);
                    state.tightTension = F1;
                    state.slackTension = F2;
                    // Net force
                    const Fnet = F1 - F2;
                    // Brake torque
                    const torque = Fnet * r;
                    state.calculatedTorque = torque;
                    // Instantaneous power at initial slip
                    const omega = (2.0 * Math.PI * state.rpm) / 60.0;
                    const power = (torque * omega) / 1000.0;
                    state.calculatedPower = power;
                    state.calculatedHP = power * 1.341;
                }
                updateUIValues();
            }
            function syncMuFromInput() {
                let val = parseFloat(inputMu.value);
                if (isNaN(val)) { val = ranges.mu.min; }
                if (val < ranges.mu.min) { val = ranges.mu.min; }
                if (val > ranges.mu.max) { val = ranges.mu.max; }
                state.mu = val;
                inputMu.value = val.toFixed(2);
                sliderMu.value = Math.round(val * 100);
                calculateClutchBrake();
            }
            function syncMuFromSlider() {
                state.mu = parseFloat(sliderMu.value) / 100;
                inputMu.value = state.mu.toFixed(2);
                calculateClutchBrake();
            }
            function syncForceFromInput() {
                let val = parseFloat(inputForce.value);
                if (isNaN(val)) { val = ranges.force.min; }
                if (val < ranges.force.min) { val = ranges.force.min; }
                if (val > ranges.force.max) { val = ranges.force.max; }
                state.force = val;
                inputForce.value = val.toFixed(0);
                sliderForce.value = Math.round(val);
                calculateClutchBrake();
            }
            function syncForceFromSlider() {
                state.force = parseFloat(sliderForce.value);
                inputForce.value = state.force.toFixed(0);
                calculateClutchBrake();
            }
            function syncRpmFromInput() {
                let val = parseFloat(inputRpm.value);
                if (isNaN(val)) { val = ranges.rpm.min; }
                if (val < ranges.rpm.min) { val = ranges.rpm.min; }
                if (val > ranges.rpm.max) { val = ranges.rpm.max; }
                state.rpm = val;
                inputRpm.value = val.toFixed(0);
                sliderRpm.value = Math.round(val);
                if (!state.engaged) {
                    state.speedIn = val;
                    if (state.mode === 'brake') { state.speedOut = val; }
                }
                calculateClutchBrake();
            }
            function syncRpmFromSlider() {
                state.rpm = parseFloat(sliderRpm.value);
                inputRpm.value = state.rpm.toFixed(0);
                if (!state.engaged) {
                    state.speedIn = state.rpm;
                    if (state.mode === 'brake') { state.speedOut = state.rpm; }
                }
                calculateClutchBrake();
            }
            // Clutch size sync
            function syncRoFromInput() {
                let val = parseFloat(inputRo.value);
                if (isNaN(val)) { val = ranges.ro.min; }
                if (val < ranges.ro.min) { val = ranges.ro.min; }
                if (val > ranges.ro.max) { val = ranges.ro.max; }
                state.ro = val;
                inputRo.value = val.toFixed(0);
                sliderRo.value = Math.round(val);
                calculateClutchBrake();
            }
            function syncRoFromSlider() {
                state.ro = parseFloat(sliderRo.value);
                inputRo.value = state.ro.toFixed(0);
                calculateClutchBrake();
            }
            function syncRiFromInput() {
                let val = parseFloat(inputRi.value);
                if (isNaN(val)) { val = ranges.ri.min; }
                if (val < ranges.ri.min) { val = ranges.ri.min; }
                if (val > ranges.ri.max) { val = ranges.ri.max; }
                state.ri = val;
                inputRi.value = val.toFixed(0);
                sliderRi.value = Math.round(val);
                calculateClutchBrake();
            }
            function syncRiFromSlider() {
                state.ri = parseFloat(sliderRi.value);
                inputRi.value = state.ri.toFixed(0);
                calculateClutchBrake();
            }
            // Brake size sync
            function syncDrumRFromInput() {
                let val = parseFloat(inputDrumR.value);
                if (isNaN(val)) { val = ranges.drumR.min; }
                if (val < ranges.drumR.min) { val = ranges.drumR.min; }
                if (val > ranges.drumR.max) { val = ranges.drumR.max; }
                state.drumR = val;
                inputDrumR.value = val.toFixed(0);
                sliderDrumR.value = Math.round(val);
                calculateClutchBrake();
            }
            function syncDrumRFromSlider() {
                state.drumR = parseFloat(sliderDrumR.value);
                inputDrumR.value = state.drumR.toFixed(0);
                calculateClutchBrake();
            }
            function syncWrapFromInput() {
                let val = parseFloat(inputWrap.value);
                if (isNaN(val)) { val = ranges.wrapAngle.min; }
                if (val < ranges.wrapAngle.min) { val = ranges.wrapAngle.min; }
                if (val > ranges.wrapAngle.max) { val = ranges.wrapAngle.max; }
                state.wrapAngle = val;
                inputWrap.value = val.toFixed(0);
                sliderWrap.value = Math.round(val);
                calculateClutchBrake();
            }
            function syncWrapFromSlider() {
                state.wrapAngle = parseFloat(sliderWrap.value);
                inputWrap.value = state.wrapAngle.toFixed(0);
                calculateClutchBrake();
            }
            function updateUIValues() {
                if (state.mode === 'clutch') {
                    // Update texts to clutch vocabulary
                    txtReadoutTitle.innerText = '전달 마찰 토크 (T)';
                    txtReadoutVal.innerText = state.calculatedTorque.toFixed(1) + ' N·m';
                    txtReadoutSub.innerText = '동력 전달 용량: ' + state.calculatedHP.toFixed(1) + ' HP (' + state.calculatedPower.toFixed(1) + ' kW)';
                    lblMetric1.innerText = '구동축 입력 속도';
                    lblMetric2.innerText = '종동축 출력 속도';
                    lblMetric3.innerText = '클러치 슬립 비율';
                    lblCard1.innerText = '평균 마찰 접촉 반경';
                    resMetric1.innerText = (state.rMean * 1000.0).toFixed(0) + ' mm';
                    lblCard2.innerText = '구동 전력 전달 용량';
                    resMetric2.innerText = state.calculatedPower.toFixed(2) + ' kW';
                    lblCard3.innerText = '미끄럼 열손실 평가';
                    if (state.mu < 0.25) {
                        resMetric3.innerText = '경고 (미끄럼 과열 위험)';
                        resMetric3.style.color = '#db2777';
                    } else {
                        resMetric3.innerText = '안전 (적정 점착 성질)';
                        resMetric3.style.color = '#10b981';
                    }
                    lblFormula1.innerText = 'T = \u03bc \u00d7 F \u00d7 R_mean';
                    lblFormula2.innerText = 'P = T \u00d7 \u03c9  [W]';
                } else {
                    // Update texts to brake vocabulary
                    txtReadoutTitle.innerText = '제동 토크 용량 (T)';
                    txtReadoutVal.innerText = state.calculatedTorque.toFixed(1) + ' N·m';
                    txtReadoutSub.innerText = '긴장측 장력 (F1): ' + state.tightTension.toFixed(0) + ' N';
                    lblMetric1.innerText = '드럼 설계 속도';
                    lblMetric2.innerText = '드럼 제동 속도';
                    lblMetric3.innerText = '제동 정지 완료 수준';
                    lblCard1.innerText = '제동 장력비 (F1/F2)';
                    const rat = state.tightTension / state.slackTension;
                    resMetric1.innerText = rat.toFixed(2);
                    lblCard2.innerText = '최대 마찰 제동 동력';
                    resMetric2.innerText = state.calculatedPower.toFixed(2) + ' kW';
                    lblCard3.innerText = '셀프 락(Self-Lock) 유무';
                    if (state.mu * state.wrapAngle * Math.PI / 180 > 2.0) {
                        resMetric3.innerText = '발생 (쐐기 고착 주의)';
                        resMetric3.style.color = '#f59e0b';
                    } else {
                        resMetric3.innerText = '미발생 (부드러운 조작)';
                        resMetric3.style.color = '#10b981';
                    }
                    lblFormula1.innerText = 'F1 / F2 = e^(\u03b1 \u00d7 \u03bc)';
                    lblFormula2.innerText = 'T_brake = (F1 - F2) \u00d7 r';
                }
            }
            function setAnalysisMode(newMode) {
                state.mode = newMode;
                state.engaged = false; // Reset to disconnected/unbraked on mode change
                state.sparks = [];
                if (newMode === 'clutch') {
                    btnModeClutch.classList.add('active');
                    btnModeBrake.classList.remove('active');
                    clutchInputs.style.display = 'flex';
                    brakeInputs.style.display = 'none';
                    txtActionBtn.innerText = '클러치 체결하기 (Engage)';
                    iconActionBtn.className = 'fa-solid fa-circle-play';
                    overlayRunStatus.innerText = '동력 전달 대기중 (클러치 분리)';
                    overlayRunStatus.style.color = '#475569';
                    state.speedIn = state.rpm;
                    state.speedOut = 0.0;
                    state.slipRatio = 1.0;
                    state.clampGap = 55.0;
                } else {
                    btnModeBrake.classList.add('active');
                    btnModeClutch.classList.remove('active');
                    clutchInputs.style.display = 'none';
                    brakeInputs.style.display = 'flex';
                    txtActionBtn.innerText = '제동 브레이크 가동 (Brake)';
                    iconActionBtn.className = 'fa-solid fa-circle-play';
                    overlayRunStatus.innerText = '제동 대기중 (드럼 무부하 회전)';
                    overlayRunStatus.style.color = '#475569';
                    state.speedIn = state.rpm;
                    state.speedOut = state.rpm;
                    state.slipRatio = 0.0;
                    state.leverAngle = 0.0;
                }
                calculateClutchBrake();
            }
            // Bindings
            btnModeClutch.addEventListener('click', function() { setAnalysisMode('clutch'); });
            btnModeBrake.addEventListener('click', function() { setAnalysisMode('brake'); });
            inputMu.addEventListener('change', syncMuFromInput);
            sliderMu.addEventListener('input', syncMuFromSlider);
            inputForce.addEventListener('change', syncForceFromInput);
            sliderForce.addEventListener('input', syncForceFromSlider);
            inputRpm.addEventListener('change', syncRpmFromInput);
            sliderRpm.addEventListener('input', syncRpmFromSlider);
            // Clutch bindings
            inputRo.addEventListener('change', syncRoFromInput);
            sliderRo.addEventListener('input', syncRoFromSlider);
            inputRi.addEventListener('change', syncRiFromInput);
            sliderRi.addEventListener('input', syncRiFromSlider);
            btnTheoryWear.addEventListener('click', function() {
                btnTheoryWear.classList.add('active');
                btnTheoryPressure.classList.remove('active');
                state.theory = 'wear';
                calculateClutchBrake();
            });
            btnTheoryPressure.addEventListener('click', function() {
                btnTheoryPressure.classList.add('active');
                btnTheoryWear.classList.remove('active');
                state.theory = 'pressure';
                calculateClutchBrake();
            });
            // Brake bindings
            inputDrumR.addEventListener('change', syncDrumRFromInput);
            sliderDrumR.addEventListener('input', syncDrumRFromSlider);
            inputWrap.addEventListener('change', syncWrapFromInput);
            sliderWrap.addEventListener('input', syncWrapFromSlider);
            // Presets
            document.getElementById('preset-car-clutch').addEventListener('click', function() {
                setActivePreset('preset-car-clutch');
                setAnalysisMode('clutch');
                state.mu = 0.38;
                state.force = 2200;
                state.rpm = 2200;
                state.ro = 220;
                state.ri = 150;
                state.theory = 'wear';
                syncControlsToState();
                calculateClutchBrake();
            });
            document.getElementById('preset-crane-brake').addEventListener('click', function() {
                setActivePreset('preset-crane-brake');
                setAnalysisMode('brake');
                state.mu = 0.45;
                state.force = 600;
                state.rpm = 800;
                state.drumR = 200;
                state.wrapAngle = 240;
                syncControlsToState();
                calculateClutchBrake();
            });
            function setActivePreset(id) {
                document.getElementById('preset-car-clutch').classList.remove('active');
                document.getElementById('preset-crane-brake').classList.remove('active');
                document.getElementById(id).classList.add('active');
            }
            function syncControlsToState() {
                inputMu.value = state.mu.toFixed(2);
                sliderMu.value = Math.round(state.mu * 100);
                inputForce.value = state.force.toFixed(0);
                sliderForce.value = Math.round(state.force);
                inputRpm.value = state.rpm.toFixed(0);
                sliderRpm.value = Math.round(state.rpm);
                if (state.mode === 'clutch') {
                    inputRo.value = state.ro.toFixed(0);
                    sliderRo.value = Math.round(state.ro);
                    inputRi.value = state.ri.toFixed(0);
                    sliderRi.value = Math.round(state.ri);
                    if (state.theory === 'wear') {
                        btnTheoryWear.classList.add('active');
                        btnTheoryPressure.classList.remove('active');
                    } else {
                        btnTheoryPressure.classList.add('active');
                        btnTheoryWear.classList.remove('active');
                    }
                } else {
                    inputDrumR.value = state.drumR.toFixed(0);
                    sliderDrumR.value = Math.round(state.drumR);
                    inputWrap.value = state.wrapAngle.toFixed(0);
                    sliderWrap.value = Math.round(state.wrapAngle);
                }
            }
            // Interactive Toggle Engine: Clutch & Brake Toggle Control Handler
            btnEngageAction.addEventListener('click', function() {
                state.engaged = !state.engaged;
                if (state.mode === 'clutch') {
                    if (state.engaged) {
                        txtActionBtn.innerText = '클러치 분리하기 (Disengage)';
                        iconActionBtn.className = 'fa-solid fa-circle-pause';
                        overlayRunStatus.innerText = '동력 전달 중 (슬립 가속 중)';
                        overlayRunStatus.style.color = '#f59e0b';
                    } else {
                        txtActionBtn.innerText = '클러치 체결하기 (Engage)';
                        iconActionBtn.className = 'fa-solid fa-circle-play';
                        overlayRunStatus.innerText = '동력 전달 대기중 (클러치 분리)';
                        overlayRunStatus.style.color = '#475569';
                    }
                } else {
                    if (state.engaged) {
                        txtActionBtn.innerText = '제동 브레이크 해제 (Release)';
                        iconActionBtn.className = 'fa-solid fa-circle-pause';
                        overlayRunStatus.innerText = '마찰 제동 가동 (감속 제동 중)';
                        overlayRunStatus.style.color = '#f59e0b';
                    } else {
                        txtActionBtn.innerText = '제동 브레이크 가동 (Brake)';
                        iconActionBtn.className = 'fa-solid fa-circle-play';
                        overlayRunStatus.innerText = '제동 대기중 (드럼 무부하 회전)';
                        overlayRunStatus.style.color = '#475569';
                    }
                }
            });
            // Canvas drawing & animation
            const canvas = document.getElementById('physics-canvas');
            const ctx = canvas.getContext('2d');
            function getDPR() { return window.devicePixelRatio || 1; }
            function initCanvas() {
                const dpr = getDPR();
                const rect = canvas.getBoundingClientRect();
                canvas.width = rect.width * dpr;
                canvas.height = rect.height * dpr;
                ctx.scale(dpr, dpr);
            }
            window.addEventListener('resize', initCanvas);
            initCanvas();
            setTimeout(initCanvas, 300);
            let lastTime = 0;
            function animate(currentTime) {
                if (lastTime === 0) { lastTime = currentTime; }
                const dt = Math.min((currentTime - lastTime) / 1000, 0.1); // Clamp dt to prevent massive jumps
                lastTime = currentTime;
                const dpr = getDPR();
                const width = canvas.width / dpr;
                const height = canvas.height / dpr;
                // Dynamic Scale Factor Calculation (Widescreen Optimized)
                const baseWidth = 800;
                const baseHeight = 500;
                const scale = Math.min(width / baseWidth, height / baseHeight);
                ctx.clearRect(0, 0, width, height);
                // Premium Blueprint grid lines
                ctx.strokeStyle = 'rgba(2, 132, 199, 0.05)';
                ctx.lineWidth = 1;
                const gridSize = 25 * scale;
                for (let x = 0; x < width; x += gridSize) {
                    ctx.beginPath(); ctx.moveTo(x, 0); ctx.lineTo(x, height); ctx.stroke();
                }
                for (let y = 0; y < height; y += gridSize) {
                    ctx.beginPath(); ctx.moveTo(0, y); ctx.lineTo(width, y); ctx.stroke();
                }
                // Render elements in absolute vertical center
                const cx = width / 2;
                const cy = height / 2;
                // Dynamic simulation math step
                if (state.mode === 'clutch') {
                    // 1. CLUTCH SIMULATION LOGIC
                    const targetGap = state.engaged ? 0.0 : 55.0;
                    state.clampGap += (targetGap - state.clampGap) * 8 * dt; // Smooth clamp transition
                    state.speedIn = state.rpm;
                    if (state.engaged) {
                        // Clutch is clamping
                        if (state.clampGap < 2.0) {
                            // Plates are in contact, calculate slip acceleration
                            // Accel scale based on Torque and damped inertia for premium 3s transition
                            const dw = (state.calculatedTorque / 12) * dt; 
                            const targetW = (2.0 * Math.PI * state.rpm) / 60.0;
                            let wOut = (2.0 * Math.PI * state.speedOut) / 60.0;
                            wOut += dw;
                            if (wOut >= targetW) {
                                wOut = targetW;
                                state.speedOut = state.rpm;
                                state.slipRatio = 0.0;
                                overlayRunStatus.innerText = '동력 체결 완료 (100% 동기화)';
                                overlayRunStatus.style.color = '#10b981';
                            } else {
                                state.speedOut = (wOut * 60.0) / (2.0 * Math.PI);
                                state.slipRatio = (state.rpm - state.speedOut) / state.rpm;
                                overlayRunStatus.innerText = '동력 전달 중 (슬립 가속 중)';
                                overlayRunStatus.style.color = '#f59e0b';
                            }
                            // Generate glowing sparks while slipping
                            if (state.slipRatio > 0.02) {
                                if (Math.random() < 0.35) {
                                    state.sparks.push({
                                        x: cx - 30 * scale + (Math.random() - 0.5) * 12 * scale,
                                        // Align with scaled-up Ro disc height
                                        y: cy + (Math.random() - 0.5) * (40 + (state.ro / 300) * 160) * scale,
                                        vx: ((Math.random() - 0.5) * 140 + 50) * scale,
                                        vy: ((Math.random() - 0.5) * 160) * scale,
                                        life: 0.7 + Math.random() * 0.3,
                                        color: Math.random() > 0.5 ? 'rgba(219,39,119,' : 'rgba(245,158,11,'
                                    });
                                }
                            }
                        } else {
                            // Moving to contact, no contact yet
                            state.slipRatio = 1.0;
                        }
                    } else {
                        // Clutch is disengaged, speed out decelerates smoothly under friction
                        const decel = 300 * dt; 
                        state.speedOut = Math.max(0.0, state.speedOut - decel);
                        state.slipRatio = 1.0;
                    }
                } else {
                    // 2. BAND BRAKE SIMULATION LOGIC
                    state.speedIn = state.rpm;
                    const targetLeverAngle = state.engaged ? 11.0 * Math.PI / 180 : 0.0;
                    state.leverAngle += (targetLeverAngle - state.leverAngle) * 8 * dt; // Smooth lever pull
                    if (state.engaged) {
                        // Braking is active, drum decelerates based on torque
                        const dw = (state.calculatedTorque / 8.0) * dt; 
                        let wDrum = (2.0 * Math.PI * state.speedOut) / 60.0;
                        wDrum -= dw;
                        if (wDrum <= 0.0) {
                            wDrum = 0.0;
                            state.speedOut = 0.0;
                            state.slipRatio = 1.0; // 100% stopped
                            overlayRunStatus.innerText = '제동 완전 정지 완료';
                            overlayRunStatus.style.color = '#10b981';
                        } else {
                            state.speedOut = (wDrum * 60.0) / (2.0 * Math.PI);
                            state.slipRatio = (state.rpm - state.speedOut) / state.rpm;
                            overlayRunStatus.innerText = '마찰 제동 가동 (감속 제동 중)';
                            overlayRunStatus.style.color = '#f59e0b';
                        }
                        // Generate circular friction sparks during deceleration
                        if (state.speedOut > 5.0) {
                            const drumCx = cx - 110 * scale;
                            const drumCy = cy;
                            // Align with scaled-up drum radius
                            const drawRad = (50.0 + (state.drumR / 300.0) * 65.0) * scale;
                            const sparkAngle = Math.random() * Math.PI * 2;
                            if (Math.random() < 0.4) {
                                state.sparks.push({
                                    x: drumCx + Math.cos(sparkAngle) * drawRad,
                                    y: drumCy + Math.sin(sparkAngle) * drawRad,
                                    vx: (-Math.sin(sparkAngle) * (state.speedOut / 8.0) + (Math.random() - 0.5) * 60) * scale,
                                    vy: (Math.cos(sparkAngle) * (state.speedOut / 8.0) + (Math.random() - 0.5) * 60) * scale,
                                    life: 0.6 + Math.random() * 0.4,
                                    color: Math.random() > 0.4 ? 'rgba(219,39,119,' : 'rgba(251,146,60,'
                                });
                            }
                        }
                    } else {
                        // Released, drum revs back up smoothly
                        state.speedOut += (state.rpm - state.speedOut) * 6 * dt;
                        state.slipRatio = (state.rpm - state.speedOut) / state.rpm;
                        if (state.rpm - state.speedOut < 1.0) {
                            state.speedOut = state.rpm;
                        }
                    }
                }
                // Update rotational angles for animation
                const wIn = (2.0 * Math.PI * state.speedIn) / 60.0;
                const wOut = (2.0 * Math.PI * state.speedOut) / 60.0;
                // Applied visual speed scale to prevent wagon-wheel strobing
                state.rotationAngleIn += wIn * 0.12 * dt;
                state.rotationAngleOut += wOut * 0.12 * dt;
                // Update indicators
                valSpeedIn.innerText = state.speedIn.toFixed(0) + ' RPM';
                valSpeedOut.innerText = state.speedOut.toFixed(0) + ' RPM';
                if (state.mode === 'clutch') {
                    valSlip.innerText = (state.slipRatio * 100.0).toFixed(1) + '%';
                } else {
                    const stopPercentage = (1.0 - state.speedOut / state.rpm) * 100.0;
                    valSlip.innerText = stopPercentage.toFixed(1) + '%';
                }
                // Render dynamic sparks particle system
                for (let i = state.sparks.length - 1; i >= 0; i--) {
                    const sp = state.sparks[i];
                    sp.x += sp.vx * dt;
                    sp.y += sp.vy * dt;
                    sp.life -= dt;
                    if (sp.life <= 0) {
                        state.sparks.splice(i, 1);
                    } else {
                        ctx.fillStyle = sp.color + sp.life + ')';
                        ctx.beginPath();
                        ctx.arc(sp.x, sp.y, (1.5 + sp.life * 2.5) * scale, 0, Math.PI * 2);
                        ctx.fill();
                    }
                }
                // Render 3D Perspective Graphic / Premium 2D Mechanism
                if (state.mode === 'clutch') {
                    // DRAWING CLUTCH: 3D Isometric View (Scale dynamic zoom)
                    const drawRo = (45 + (state.ro / 300) * 80) * scale;
                    const drawRi = drawRo * (state.ri / state.ro);
                    // Widen the layout to make full use of the wide canvas space
                    const leftDiskX = cx - 90 * scale;
                    const leftShaftX = cx - 280 * scale;
                    const currentGap = state.clampGap * scale;
                    const rightDiskX = cx + 30 * scale + currentGap;
                    const rightShaftX = rightDiskX + 18 * scale;
                    // 1. LEFT SHAFTS (3D Cylinder - Dynamic length)
                    ctx.save();
                    const shaftGrad = ctx.createLinearGradient(leftShaftX, cy - 19 * scale, leftShaftX, cy + 19 * scale);
                    shaftGrad.addColorStop(0, '#0f172a');
                    shaftGrad.addColorStop(0.3, '#334155');
                    shaftGrad.addColorStop(0.7, '#64748b');
                    shaftGrad.addColorStop(1, '#0f172a');
                    ctx.fillStyle = shaftGrad;
                    ctx.beginPath();
                    ctx.rect(leftShaftX, cy - 19 * scale, leftDiskX - leftShaftX, 38 * scale);
                    ctx.fill();
                    // Left Input shaft 3D end face
                    ctx.fillStyle = '#1e293b';
                    ctx.beginPath();
                    ctx.ellipse(leftShaftX, cy, 8 * scale, 19 * scale, 0, 0, Math.PI * 2);
                    ctx.fill();
                    ctx.restore();
                    // 2. LEFT DRIVING DISC
                    ctx.save();
                    ctx.shadowBlur = 20 * scale;
                    ctx.shadowColor = 'rgba(2, 132, 199, 0.22)';
                    const discLeftGrad = ctx.createLinearGradient(leftDiskX, cy - drawRo, leftDiskX + 30 * scale, cy + drawRo);
                    discLeftGrad.addColorStop(0, '#0369a1');
                    discLeftGrad.addColorStop(0.5, '#0284c7');
                    discLeftGrad.addColorStop(1, '#0f766e');
                    ctx.fillStyle = discLeftGrad;
                    ctx.strokeStyle = '#0284c7';
                    ctx.lineWidth = 2 * scale;
                    ctx.beginPath();
                    ctx.ellipse(leftDiskX, cy, 18 * scale, drawRo, 0, 0, Math.PI * 2);
                    ctx.fill();
                    ctx.stroke();
                    ctx.restore();
                    // Radial Slots on Left Plate
                    ctx.save();
                    ctx.strokeStyle = 'rgba(255, 255, 255, 0.5)';
                    ctx.lineWidth = 3 * scale;
                    const slots = 8;
                    for (let i = 0; i < slots; i++) {
                        const phi = state.rotationAngleIn + (i * Math.PI * 2) / slots;
                        const outerX = leftDiskX + Math.cos(phi) * 16 * scale;
                        const outerY = cy + Math.sin(phi) * drawRo;
                        const innerX = leftDiskX + Math.cos(phi) * 6 * scale;
                        const innerY = cy + Math.sin(phi) * drawRi;
                        ctx.beginPath();
                        ctx.moveTo(innerX, innerY);
                        ctx.lineTo(outerX, outerY);
                        ctx.stroke();
                    }
                    ctx.restore();
                    // 3. FRICTION LINING PAD LAYER
                    ctx.save();
                    ctx.fillStyle = '#1e293b';
                    ctx.strokeStyle = '#475569';
                    ctx.lineWidth = 1 * scale;
                    ctx.beginPath();
                    ctx.ellipse(leftDiskX + 11 * scale, cy, 8 * scale, drawRo - 1 * scale, 0, 0, Math.PI * 2);
                    ctx.fill();
                    ctx.stroke();
                    ctx.fillStyle = '#cbd5e1';
                    ctx.beginPath();
                    ctx.ellipse(leftDiskX + 11 * scale, cy, 5 * scale, drawRi, 0, 0, Math.PI * 2);
                    ctx.fill();
                    ctx.restore();
                    // 4. RIGHT DRIVEN DISC
                    ctx.save();
                    const discRightGrad = ctx.createLinearGradient(rightDiskX, cy - drawRo, rightDiskX + 30 * scale, cy + drawRo);
                    discRightGrad.addColorStop(0, '#db2777');
                    discRightGrad.addColorStop(0.5, '#ec4899');
                    discRightGrad.addColorStop(1, '#db2777');
                    ctx.fillStyle = discRightGrad;
                    ctx.strokeStyle = '#f472b6';
                    ctx.lineWidth = 2 * scale;
                    ctx.beginPath();
                    ctx.ellipse(rightDiskX, cy, 18 * scale, drawRo, 0, 0, Math.PI * 2);
                    ctx.fill();
                    ctx.stroke();
                    ctx.restore();
                    // Radial slots on Right Plate
                    ctx.save();
                    ctx.strokeStyle = 'rgba(255, 255, 255, 0.5)';
                    ctx.lineWidth = 3 * scale;
                    for (let i = 0; i < slots; i++) {
                        const phi = state.rotationAngleOut + (i * Math.PI * 2) / slots;
                        const outerX = rightDiskX + Math.cos(phi) * 16 * scale;
                        const outerY = cy + Math.sin(phi) * drawRo;
                        const innerX = rightDiskX + Math.cos(phi) * 6 * scale;
                        const innerY = cy + Math.sin(phi) * drawRi;
                        ctx.beginPath();
                        ctx.moveTo(innerX, innerY);
                        ctx.lineTo(outerX, outerY);
                        ctx.stroke();
                    }
                    ctx.restore();
                    // 5. RIGHT OUTPUT SHAFT
                    ctx.save();
                    const rightShaftGrad = ctx.createLinearGradient(rightShaftX, cy - 19 * scale, rightShaftX, cy + 19 * scale);
                    rightShaftGrad.addColorStop(0, '#334155');
                    rightShaftGrad.addColorStop(0.3, '#475569');
                    rightShaftGrad.addColorStop(0.7, '#94a3b8');
                    rightShaftGrad.addColorStop(1, '#334155');
                    ctx.fillStyle = rightShaftGrad;
                    ctx.beginPath();
                    ctx.rect(rightShaftX, cy - 19 * scale, (cx + 280 * scale) - rightShaftX, 38 * scale);
                    ctx.fill();
                    ctx.strokeStyle = 'rgba(255, 255, 255, 0.25)';
                    ctx.lineWidth = 4 * scale;
                    const shaftLineX = rightDiskX + 70 * scale;
                    const lineOffset = (state.rotationAngleOut * 120 * scale) % (50 * scale);
                    ctx.beginPath();
                    ctx.moveTo(shaftLineX + lineOffset, cy - 19 * scale);
                    ctx.lineTo(shaftLineX + lineOffset, cy + 19 * scale);
                    ctx.stroke();
                    ctx.restore();
                    // 6. ACTION EFFECTS: GLOW &#038; PRESSURE ARROWS
                    if (state.engaged) {
                        ctx.save();
                        if ((state.clampGap < 3.0) ? (state.slipRatio > 0.0) : false) {
                            const heatIntensity = state.slipRatio;
                            ctx.strokeStyle = 'rgba(239, 68, 68, ' + (0.3 + heatIntensity * 0.5) + ')';
                            ctx.shadowBlur = 30 * scale;
                            ctx.shadowColor = '#ef4444';
                            ctx.lineWidth = 14 * scale;
                            ctx.beginPath();
                            ctx.ellipse(cx - 30 * scale, cy, 24 * scale, drawRo + 8 * scale, 0, 0, Math.PI * 2);
                            ctx.stroke();
                        }
                        ctx.strokeStyle = '#db2777';
                        ctx.fillStyle = '#db2777';
                        ctx.lineWidth = 5 * scale;
                        ctx.shadowBlur = 12 * scale;
                        ctx.shadowColor = '#db2777';
                        const arrowHeadX = rightDiskX + 32 * scale;
                        ctx.beginPath(); ctx.moveTo(arrowHeadX + 80 * scale, cy - 45 * scale); ctx.lineTo(arrowHeadX, cy - 45 * scale); ctx.stroke();
                        ctx.beginPath(); ctx.moveTo(arrowHeadX, cy - 45 * scale); ctx.lineTo(arrowHeadX + 10 * scale, cy - 51 * scale); ctx.lineTo(arrowHeadX + 10 * scale, cy - 39 * scale); ctx.closePath(); ctx.fill();
                        ctx.beginPath(); ctx.moveTo(arrowHeadX + 80 * scale, cy + 45 * scale); ctx.lineTo(arrowHeadX, cy + 45 * scale); ctx.stroke();
                        ctx.beginPath(); ctx.moveTo(arrowHeadX, cy + 45 * scale); ctx.lineTo(arrowHeadX + 10 * scale, cy + 51 * scale); ctx.lineTo(arrowHeadX + 10 * scale, cy + 39 * scale); ctx.closePath(); ctx.fill();
                        ctx.restore();
                    }
                } else {
                    // DRAWING BAND BRAKE: High-Fidelity Drum (Scale dynamic zoom)
                    const drawRad = (50.0 + (state.drumR / 300.0) * 65.0) * scale;
                    const drumCx = cx - 110 * scale;
                    const drumCy = cy;
                    // 1. BRAKE DRUM
                    ctx.save();
                    ctx.translate(drumCx, drumCy);
                    ctx.rotate(state.rotationAngleOut);
                    ctx.shadowBlur = 25 * scale;
                    ctx.shadowColor = 'rgba(71, 85, 105, 0.15)';
                    const drumGrad = ctx.createRadialGradient(0, 0, 10 * scale, 0, 0, drawRad);
                    drumGrad.addColorStop(0, '#ffffff');
                    drumGrad.addColorStop(0.5, '#cbd5e1');
                    drumGrad.addColorStop(0.95, '#94a3b8');
                    drumGrad.addColorStop(1, '#475569');
                    ctx.fillStyle = drumGrad;
                    ctx.strokeStyle = '#1e293b';
                    ctx.lineWidth = 5.5 * scale;
                    ctx.beginPath();
                    ctx.arc(0, 0, drawRad, 0, Math.PI * 2);
                    ctx.fill();
                    ctx.stroke();
                    // Drastically reduced holes
                    ctx.fillStyle = '#334155';
                    const holes = 3;
                    for (let i = 0; i < holes; i++) {
                        const holeAngle = (i * Math.PI * 2) / holes;
                        const hx = Math.cos(holeAngle) * (drawRad - 18 * scale);
                        const hy = Math.sin(holeAngle) * (drawRad - 18 * scale);
                        ctx.beginPath();
                        ctx.arc(hx, hy, 7 * scale, 0, Math.PI * 2);
                        ctx.fill();
                    }
                    // Prominent high-contrast line/marker
                    ctx.strokeStyle = '#0284c7';
                    ctx.lineWidth = 5 * scale;
                    ctx.beginPath();
                    ctx.moveTo(0, 0);
                    ctx.lineTo(drawRad - 6 * scale, 0);
                    ctx.stroke();
                    // Elegant Internal spokes
                    ctx.strokeStyle = '#64748b';
                    ctx.lineWidth = 5 * scale;
                    for (let i = 0; i < 4; i++) {
                        const spokeA = (i * Math.PI) / 2;
                        ctx.beginPath(); ctx.moveTo(0, 0); ctx.lineTo(Math.cos(spokeA) * (drawRad - 22 * scale), Math.sin(spokeA) * (drawRad - 22 * scale)); ctx.stroke();
                    }
                    // Heavy center axle pin
                    ctx.fillStyle = '#0f172a';
                    ctx.strokeStyle = '#cbd5e1';
                    ctx.lineWidth = 3 * scale;
                    ctx.beginPath(); ctx.arc(0, 0, 16 * scale, 0, Math.PI * 2); ctx.fill(); ctx.stroke();
                    ctx.restore();
                    // 2. TIGHT &#038; SLACK LEVER SYSTEM (Lever Joint Anchor Mechanics)
                    ctx.save();
                    const wAngRad = (state.wrapAngle * Math.PI) / 180.0;
                    const startA = Math.PI - wAngRad / 2.0;
                    const anchorHingeX = drumCx + drawRad + 35 * scale;
                    const anchorHingeY = drumCy + drawRad * 0.4;
                    // Draw static support frame
                    ctx.strokeStyle = '#94a3b8';
                    ctx.lineWidth = 6 * scale;
                    ctx.lineCap = 'round';
                    ctx.beginPath();
                    ctx.moveTo(anchorHingeX, anchorHingeY);
                    ctx.lineTo(anchorHingeX - 12 * scale, anchorHingeY + 25 * scale);
                    ctx.stroke();
                    // Ground hash lines
                    ctx.lineWidth = 2 * scale;
                    ctx.beginPath();
                    ctx.moveTo(anchorHingeX - 20 * scale, anchorHingeY + 25 * scale);
                    ctx.lineTo(anchorHingeX - 4 * scale, anchorHingeY + 25 * scale);
                    ctx.stroke();
                    // Joint Pin anchor pivot
                    ctx.fillStyle = '#475569';
                    ctx.beginPath(); ctx.arc(anchorHingeX, anchorHingeY, 7 * scale, 0, Math.PI * 2); ctx.fill();
                    // Solid operating lever bar
                    const leverLength = 180 * scale;
                    const endLeverX = anchorHingeX + Math.cos(state.leverAngle) * leverLength;
                    const endLeverY = anchorHingeY + Math.sin(state.leverAngle) * leverLength;
                    ctx.strokeStyle = '#475569';
                    ctx.lineWidth = 9 * scale;
                    ctx.beginPath();
                    ctx.moveTo(anchorHingeX, anchorHingeY);
                    ctx.lineTo(endLeverX, endLeverY);
                    ctx.stroke();
                    // F1 &#038; F2 attachment pins
                    const tightPinDist = 32 * scale;
                    const slackPinDist = 78 * scale;
                    const pinTightX = anchorHingeX + Math.cos(state.leverAngle) * tightPinDist;
                    const pinTightY = anchorHingeY + Math.sin(state.leverAngle) * tightPinDist;
                    const pinSlackX = anchorHingeX + Math.cos(state.leverAngle) * slackPinDist;
                    const pinSlackY = anchorHingeY + Math.sin(state.leverAngle) * slackPinDist;
                    ctx.fillStyle = '#0284c7';
                    ctx.beginPath(); ctx.arc(pinTightX, pinTightY, 4.5 * scale, 0, Math.PI * 2); ctx.fill();
                    ctx.fillStyle = '#db2777';
                    ctx.beginPath(); ctx.arc(pinSlackX, pinSlackY, 4.5 * scale, 0, Math.PI * 2); ctx.fill();
                    // 3. BRAKE STRAP BAND (Glows red-hot under friction deceleration)
                    ctx.save();
                    if (state.engaged ? (state.speedOut > 0.0) : false) {
                        ctx.strokeStyle = 'rgba(239, 68, 68, 0.45)';
                        ctx.shadowBlur = 18 * scale;
                        ctx.shadowColor = '#ef4444';
                        ctx.lineWidth = 11 * scale;
                        ctx.beginPath();
                        ctx.arc(drumCx, drumCy, drawRad + 3 * scale, startA, startA + wAngRad);
                        ctx.stroke();
                    }
                    // Strap structure
                    ctx.strokeStyle = '#db2777';
                    ctx.lineWidth = state.engaged ? 7.5 * scale : 4.0 * scale;
                    ctx.lineCap = 'round';
                    ctx.beginPath();
                    const bandPoints = 90;
                    for (let i = 0; i <= bandPoints; i++) {
                        const phi = startA + (i / bandPoints) * wAngRad;
                        const strapDistance = state.engaged ? drawRad + 2.0 * scale : drawRad + 7.5 * scale;
                        const bx = drumCx + Math.cos(phi) * strapDistance;
                        const by = drumCy + Math.sin(phi) * strapDistance;
                        if (i === 0) { ctx.moveTo(bx, by); }
                        else { ctx.lineTo(bx, by); }
                    }
                    ctx.stroke();
                    // Links from strap to pins
                    ctx.strokeStyle = '#cbd5e1';
                    ctx.lineWidth = 3.5 * scale;
                    const bandStartStrapX = drumCx + Math.cos(startA) * (state.engaged ? drawRad + 2.0 * scale : drawRad + 7.5 * scale);
                    const bandStartStrapY = drumCy + Math.sin(startA) * (state.engaged ? drawRad + 2.0 * scale : drawRad + 7.5 * scale);
                    const bandEndStrapX = drumCx + Math.cos(startA + wAngRad) * (state.engaged ? drawRad + 2.0 * scale : drawRad + 7.5 * scale);
                    const bandEndStrapY = drumCy + Math.sin(startA + wAngRad) * (state.engaged ? drawRad + 2.0 * scale : drawRad + 7.5 * scale);
                    ctx.beginPath();
                    ctx.moveTo(bandStartStrapX, bandStartStrapY);
                    ctx.lineTo(pinSlackX, pinSlackY);
                    ctx.moveTo(bandEndStrapX, bandEndStrapY);
                    ctx.lineTo(pinTightX, pinTightY);
                    ctx.stroke();
                    ctx.restore();
                    // 4. DESIGN DIRECTION FORCE VECTOR (Pink vector on the lever)
                    if (state.engaged) {
                        ctx.save();
                        ctx.strokeStyle = '#db2777';
                        ctx.fillStyle = '#db2777';
                        ctx.lineWidth = 4 * scale;
                        ctx.shadowBlur = 8 * scale;
                        ctx.shadowColor = '#db2777';
                        ctx.beginPath(); ctx.moveTo(endLeverX, endLeverY - 45 * scale); ctx.lineTo(endLeverX, endLeverY - 4 * scale); ctx.stroke();
                        ctx.beginPath(); ctx.moveTo(endLeverX, endLeverY - 4 * scale); ctx.lineTo(endLeverX - 6 * scale, endLeverY - 14 * scale); ctx.lineTo(endLeverX + 6 * scale, endLeverY - 14 * scale); ctx.closePath(); ctx.fill();
                        ctx.font = '700 ' + (11 * scale) + 'px Inter';
                        ctx.fillText('인가력 F', endLeverX - 8 * scale, endLeverY - 50 * scale);
                        ctx.restore();
                    }
                }
                requestAnimationFrame(animate);
            }
            requestAnimationFrame(animate);
            // Initial calculations
            calculateClutchBrake();
            // Right click / Copy Protection
            (function() {
                function blockEvents() {
                    document.addEventListener('contextmenu', function(e) {
                        e.preventDefault();
                        alert("이 콘텐츠는 저작권법의 보호를 받습니다. 무단 복제 및 우클릭을 금지합니다.");
                        return false;
                    }, { capture: true });
                    document.addEventListener('selectstart', function(e) {
                        e.preventDefault();
                        return false;
                    }, { capture: true });
                }
                if (document.readyState === 'complete' || document.readyState === 'interactive') {
                    blockEvents();
                } else {
                    document.addEventListener('DOMContentLoaded', blockEvents);
                }
            })();
        })();
</script>


<div style="background: linear-gradient(135deg, rgba(0,242,254,0.03), rgba(138,43,226,0.03)); border: 1px solid rgba(0,242,254,0.15); border-radius: 12px; padding: 18px 24px; margin: 25px auto 35px auto; font-size: 0.95em; color: #4b5563; line-height: 1.7; font-family: sans-serif;">
    <strong style="color: #1f2937; font-size: 1.05em; display: flex; align-items: center; gap: 8px;">
        <span style="font-size: 1.2em;"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f4a1.png" alt="💡" class="wp-smiley" style="height: 1em; max-height: 1em;" /></span> 간편 사용 설명서
    </strong>
    <ol style="margin: 10px 0 0 0; padding-left: 20px;">
        <li style="margin-bottom: 6px;"><strong>구동 해석 장치 선택: '단판 마찰 클러치' 분석 모드 또는 '밴드 제동 브레이크' 분석 모드를 선택합니다.</strong></li>
<li style="margin-bottom: 6px;">기본 마찰 조건 설정: 접촉면의 마찰 계수(mu)와 작동 수직 클램핑 힘(F)을 지정합니다.</li>
<li style="margin-bottom: 6px;">기하 형상 입력: 클러치 외경/내경(Ro, Ri) 및 마모 이론(마모설 vs 압력설)을 지정하거나, 브레이크 드럼 직경(D) 및 밴드 감김 랩 각도(theta)를 지정합니다.</li>
<li style="margin-bottom: 6px;">구동 속도 RPM 인가: 입력축의 구동 속도(N)를 설정합니다.</li>
<li style="margin-bottom: 6px;">실시간 체결 및 제동 동역학 감상: '체결/제동 구동(Engage / Brake)' 버튼을 클릭해 2D 물리 시뮬레이션 속에서 클러치가 미끄러지며(Slip) 가속되거나, 밴드가 드럼을 감싸 쥐어 회전 속도가 서서히 정지하는 역학 관계를 실시간으로 확인합니다.</li>
    </ol>
</div>


<details class="premium-seo-accordion" style="border: 1px solid rgba(0,0,0,0.08); border-radius: 12px; background: #fbfbfc; padding: 0; margin: 30px auto; box-shadow: 0 4px 6px -1px rgba(0,0,0,0.01); font-family: sans-serif;">
    <summary style="display: flex; justify-content: space-between; align-items: center; padding: 20px 24px; font-size: 1.1em; font-weight: 700; color: #1f2937; cursor: pointer; user-select: none; outline: none; list-style: none;">
        <span><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f4da.png" alt="📚" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 상세 기계공학 해설 및 마찰 체결 기구 설계 식 확인하기</span>
        <span class="accordion-arrow" style="font-size: 0.9em; color: #9ca3af; transition: transform 0.2s ease;">▼</span>
    </summary>
    <div style="padding: 0 24px 24px 24px; border-top: 1px solid rgba(0,0,0,0.04); background: #ffffff; border-radius: 0 0 12px 12px; font-size: 0.98em; color: #374151; line-height: 1.8;">
        <div style="margin-top: 20px;">
            <h3>1. 마찰 클러치의 두 가지 설계 가설: 일등 마모설 vs 일등 압력설</h3>
<p>마찰 클러치(Friction Clutch)는 주동축의 동력을 종동축으로 부드럽게 연결하거나 차단하는 장치로, 면마찰 접촉 조건에 대해 다음과 같은 두 가지 극단적인 설계 가설이 쓰입니다:</p><ul><li><strong>일등 마모설 (Uniform Wear Theory):</strong> 마찰면 전체의 물리적 마모율(압력 p &times; 미끄럼속도 v)이 일정하다고 가정합니다. 클러치가 길들어 오랜 기간 사용된 상태(Worn-in)에 적합하며, 안전 마진 확보를 위해 <u>실무 설계 시 표준</u>으로 채택됩니다. 평균 마찰 반경은 다음과 같습니다:<br><code style="background:#f3f4f6; padding:2px 6px; border-radius:4px;">R<sub>mean</sub> = (R<sub>i</sub> + R<sub>o</sub>) / 2</code></li><li><strong>일등 압력설 (Uniform Pressure Theory):</strong> 접촉면 전체에 작용하는 단위 면적당 면압(p)이 완전히 균일하다고 가정합니다. 마찰재가 단단하고 평평하게 맞닿은 신품 클러치(New Clutch) 상태에 적합합니다. 평균 마찰 반경은 다음과 같습니다:<br><code style="background:#f3f4f6; padding:2px 6px; border-radius:4px;">R<sub>mean</sub> = 2/3 &middot; (R<sub>o</sub><sup>3</sup> - R<sub>i</sub><sup>3</sup>) / (R<sub>o</sub><sup>2</sup> - R<sub>i</sub><sup>2</sup>)</code></li></ul><p>클러치 전달 토크는 <code>T = &mu; &middot; F &middot; R<sub>mean</sub></code>으로 계산되며, 전달 동력은 <code>P = T &middot; &omega;</code>이 성립합니다.</p>
<h3>2. 밴드 브레이크와 벨트 마찰 방정식 (오일러-아이텔바인 공식)</h3>
<p><strong>밴드 브레이크 (Band Brake)</strong>는 회전하는 드럼 외주면에 유연한 강철 마찰 밴드를 둘러싸고, 레버를 통해 밴드를 강하게 당겨 마찰 저항력으로 제동을 거는 고토크 제동 장치입니다.</p><p>드럼에 밀착된 벨트의 긴장측(Tight Side) 장력 <code>F<sub>1</sub></code>과 이완측(Slack Side) 장력 <code>F<sub>2</sub></code> 사이의 수학적 관계는 오일러의 <strong>벨트 마찰 공식(Euler-Eytelwein Equation)</strong>을 충실히 따릅니다:</p><p style="text-align: center; font-weight: bold; background: #e0f2fe; padding: 16px; border-radius: 8px; font-size: 1.1em; color: #0369a1;">F<sub>1</sub> / F<sub>2</sub> = e<sup>&mu; &middot; &alpha;</sup> &nbsp;&nbsp;(여기서 &alpha;는 라디안 단위의 감김각 랩앵글)</p><p>제동 레버 조작력에 의한 이완측 장력이 <code>F<sub>2</sub> = F</code>일 때, 전달(제동)되는 유효 힘은 <code>F<sub>net</sub> = F<sub>1</sub> - F<sub>2</sub> = F &middot; (e<sup>&mu;&alpha;</sup> - 1)</code>이 되며, 드럼 반경 <code>r</code>에 작용하는 제동 토크는 다음과 같이 유도되어 랩 각도가 커질수록 제동력이 기하급수적으로 폭증합니다:</p><p style="text-align: center; font-weight: bold; background: #f3f4f6; padding: 12px; border-radius: 8px;">T<sub>brake</sub> = F &middot; (e<sup>&mu;&alpha;</sup> - 1) &middot; r &nbsp;[N&middot;m]</p>
        </div>
    </div>
</details>
<style>
details.premium-seo-accordion[open] summary .accordion-arrow { transform: rotate(180deg); color: #00f2fe; }
details.premium-seo-accordion summary::-webkit-details-marker { display: none; }
details.premium-seo-accordion:hover { border-color: rgba(0,242,254,0.3); }
</style>

]]></content:encoded>
					
					<wfw:commentRss>https://myengnote.com/clutch-brake-torque-power-simulator/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
